Reputation: 313
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.
Upvotes: 1
Views: 1665
Reputation: 1561
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.
Upvotes: 3
Reputation: 21762
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
Upvotes: 1
Reputation: 564
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.
Upvotes: 2