Detecting unassigned values ​​in angular directives

I have a directive that will get / set focus on an element based on the value.

When the element is focused or blurred, the directive will update the boolean. However, sometimes I only need to set focus when a condition is met, and I use a non-assignable value that causes this error:

Error: [$compile:nonassign] Expression '$last && !domain.url' used with directive 'focusWhen' is non-assignable!

WORKING DEMO HERE (check your console for errors)

I understand why it is throwing an error, but how can I define non-assignable values ​​from within the directive and then prevent it from attaching focus / blur events that try to assign a value when the focus changes?


Here's an example of using a directive used with an untranslatable value. In this case, it will focus on the last element of the repeater if it is also empty

<div ng-repeat="domain in domainList">
  <input type="text" ng-model="domain.url" focus-when="$last && !domain.url"/>
</div>

      

And here is the directive code

testApp.directive("focusWhen", ["$timeout", function ($timeout) {

    function getLink($scope, $element) {
        $scope.$watch("focusWhen", function (val) {
            //only focus when needed and when this element doesn't already have focus
            if (val && $element[0] !== document.activeElement) {
                //Small delay needed before we can get focus properly
                $timeout(function () {
                    $element.focus();
                });
            }
        });
        $element.on("blur.focusWhen", function () {
            if ($scope.focusWhen) {
                $timeout(function () {
                    $scope.focusWhen = false;
                });
            }
        });
        $element.on("focus.focusWhen", function () {
            if (!$scope.focusWhen) {
                $timeout(function () {
                    $scope.focusWhen = true;
                });
            }
        });
    }

    return {
        restrict: "A",
        scope: {
            focusWhen: "="
        },
        link: getLink
    };
}]);

      

+3


source to share


1 answer


Update

The programmatic way of detecting this (instead of having another attribute) is using $parse

fn. This is how angular checks and throws an error. It tries to parse the bi-directional binding attribute, and if it has no destination attribute, it throws an error. ($parse($attrs['focusWhen']).assign)

...

http://jsfiddle.net/cw7fftfx/




Old answer:

How about another attribute indicating whether you want to return the focus value?

<input type="text" ng-model="domain.url" one-way="true" focus-when="$last && !domain.url"/>

    $element.on("blur.focusWhen", function () {
        if ($scope.focusWhen) {
            $timeout(function () {
                if (!$attr.oneWay) {
                $scope.focusWhen = false;
                }
            });
        }
    });

      

http://jsfiddle.net/j1v6jk8k/3/

+1


source







All Articles