Angular $watch does not fire any event in my directive

别等时光非礼了梦想. 提交于 2019-12-24 10:44:47

问题


i try to update an elements content depending on the attribute value of my custom directive. the code below performs well but only once on site-load. dynamic updates on the attribute value do not fire any event. what do i do wrong?

markup inside ng-repeat (match in matches):

<div ng-tipp-result="[[getIconClass(match)]]"></div>

directive:

myApp.directive('ngTippResult', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            var content = "s";

            scope.$watch(attrs.ngTippResult, function(v){
                switch(v){
                    case 1: content = '<i class="icon-circle"></i>';break;
                    case 2: content = '<i class="icon-X"></i>';break;
                    case 3: content = '<i class="icon-Y"></i>';break;
                    case 4: content = '<i class="icon-Z"></i>';break;
                    case 5: content = '<i class="icon-ok"></i>';break;
                    case 6: content = '<i class="icon-minus"></i>';break;
                }

                elem.html(content);
            });
        }
    };
});

Edit:

using the attributes name as string solved the problem but caused another, i ran into a infinit digest loop with the code above.

<li ng-repeat="match in matches">
    <i class="pull-right [[getIconClass(match)]]"></i>
</li>

getIconClass is a controller method which returns values from 1 to 6 depending on match.


回答1:


The first parameter to $watch should be a getter function for the value you want to watch. Try

scope.$watch(function(){return attrs.ngTippResult}, function(v){...});

See the docs here.

What's probably happening is that attrs.ngTippResult is evaluating to a String. A String is a valid input, but I don't think that's what you intended; it seems like you want an update everytime attrs.ngTippResult changes. Instead, your current code is watching the property on the scope with the value of attrs.ngTippResult (for example, if attrs.ngTippResult was "fish", the value you would be watching with your current code would actually be $scope.fish, which probably isn't what you want.

EDIT

Also, aaronfrost's answer might be the best for what you're trying to do.




回答2:


You can map the attribute to your directive scope:

myApp.directive('ngTippResult', function() { return { scope: { theTippResult:"=ngTippResult", ...}}});

then you'll just need to put the variable name in a string: scope.$watch('theTippResult', function(v){...});

--Or-- use the function method like Hylianpuffball suggested, though I'd still map it to your model just as 'self documenting' code.




回答3:


For the attrs object in the directive, you should not use scope.$watch. You should use attrs.$observe. It was built to allow you to watch the attribute values, without doing a watch. However, the syntax is almost identical.

See the doc here



来源:https://stackoverflow.com/questions/20623715/angular-watch-does-not-fire-any-event-in-my-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!