How to watch property in attrs of directive

后端 未结 5 1481
难免孤独
难免孤独 2020-12-25 14:44

I have a controller that has a counter that changes from time to time.
That counter is tied to an attribute of a directive and read inside the link function of that dire

相关标签:
5条回答
  • 2020-12-25 15:16

    If you can, change the directive to isolated scope and use the = definition. This will set up a two-way binding for the scope property:

    app.directive('myDirective', function() {
    
        return {
            scope: { counter: '=' }
        }
    });
    
    0 讨论(0)
  • 2020-12-25 15:17

    Inside your corresponding link function: (assuming your attribute is called counter and your scope variable is: scope)

    scope.$watch(attrs.counter, function (newTime) {
                        //do something with the new Time
    });
    

    Other way, surely more efficient way:

    Interpolating the attribute

    Inside your directive, set the scope property as following (it will be isolated so):

    scope: { counter: '@'}
    

    The counter would automatically be observed providing the current value as long as the link function is called.

    '@' better than '=' here since you I suppose you don't set the counter to a new value in your directive, meaning you just read it. Indeed, = is more useful for two-way data binding but you might not need it.

    0 讨论(0)
  • 2020-12-25 15:20

    Use attrs.$observe(key, fn). More info at $compile.directive.Attributes

    attrs.$observe('counter',function(counter){
    
    });
    

    Related answer: https://stackoverflow.com/a/14907826/2874153

    $observe() is a method on the Attributes object, and as such, it can only be used to observe/watch the value change of a DOM attribute. It is only used/called inside directives. Use $observe when you need to observe/watch a DOM attribute that contains interpolation (i.e., {{}}'s). E.g., attr1="Name: {{name}}", then in a directive: attrs.$observe('attr1', ...). (If you try scope.$watch(attrs.attr1, ...) it won't work because of the {{}}s -- you'll get undefined.) Use $watch for everything else.

    0 讨论(0)
  • 2020-12-25 15:29

    I had to implement this myself and found a solution! Unfortunately, when I tried .$watch, errors were just spewing out on the console. So I used $observe instead.

    Here's my solution:

    angular.module('app').directive('aDate', [
        function() {
            return {
                template: '<span>{{date}}</span>',
                restrict: 'E',
                replace: true,
                link: function(scope, element, attrs) {
                    attrs.$observe('date', function (val) {
                        var d = new Date(val);
                        element.text(d);
                    });
                }
            };
        }
    ]);
    

    The above code changes the scoped date when the date attribute of the element changes!

    Cheers!

    0 讨论(0)
  • 2020-12-25 15:31

    I am using this aproach:

    .directive('mydirective',
     [function (){
        return {
          ...
          scope: {
            id: '@',
          },
          controller: function ($scope, $element, $attrs) {
             $attrs.$observe('id', function(passedId) {
               /// do what is needed with passedId
             });
        ...
    

    And the directive used and id passed like this:

    <div mydirective id="{{someprop.id}}" />
    
    0 讨论(0)
提交回复
热议问题