Angular Directive refresh on parameter change

131,843

Solution 1

Link function only gets called once, so it would not directly do what you are expecting. You need to use angular $watch to watch a model variable.

This watch needs to be setup in the link function.

If you use isolated scope for directive then the scope would be

scope :{typeId:'@' }

In your link function then you add a watch like

link: function(scope, element, attrs) {
    scope.$watch("typeId",function(newValue,oldValue) {
        //This gets called when data changes.
    });
 }

If you are not using isolated scope use watch on some_prop

Solution 2

What you're trying to do is to monitor the property of attribute in directive. You can watch the property of attribute changes using $observe() as follows:

angular.module('myApp').directive('conversation', function() {
  return {
    restrict: 'E',
    replace: true,
    compile: function(tElement, attr) {
      attr.$observe('typeId', function(data) {
            console.log("Updated data ", data);
      }, true);

    }
  };
});

Keep in mind that I used the 'compile' function in the directive here because you haven't mentioned if you have any models and whether this is performance sensitive.

If you have models, you need to change the 'compile' function to 'link' or use 'controller' and to monitor the property of a model changes, you should use $watch(), and take of the angular {{}} brackets from the property, example:

<conversation style="height:300px" type="convo" type-id="some_prop"></conversation>

And in the directive:

angular.module('myApp').directive('conversation', function() {
  return {
    scope: {
      typeId: '=',
    },
    link: function(scope, elm, attr) {

      scope.$watch('typeId', function(newValue, oldValue) {
          if (newValue !== oldValue) {
            // You actions here
            console.log("I got the new value! ", newValue);
          }
      }, true);

    }
  };
});

Solution 3

I hope this will help reloading/refreshing directive on value from parent scope

<html>

        <head>
            <!-- version 1.4.5 -->
            <script src="angular.js"></script>
        </head>

        <body ng-app="app" ng-controller="Ctrl">

            <my-test reload-on="update"></my-test><br>
            <button ng-click="update = update+1;">update {{update}}</button>
        </body>
        <script>
            var app = angular.module('app', [])
            app.controller('Ctrl', function($scope) {

                $scope.update = 0;
            });
            app.directive('myTest', function() {
                return {
                    restrict: 'AE',
                    scope: {
                        reloadOn: '='
                    },
                    controller: function($scope) {
                        $scope.$watch('reloadOn', function(newVal, oldVal) {
                            //  all directive code here
                            console.log("Reloaded successfully......" + $scope.reloadOn);
                        });
                    },
                    template: '<span>  {{reloadOn}} </span>'
                }
            });
        </script>


   </html>
Share:
131,843

Related videos on Youtube

Luke Sapan
Author by

Luke Sapan

Updated on July 05, 2022

Comments

  • Luke Sapan
    Luke Sapan about 2 years

    I have an angular directive which is initialized like so:

    <conversation style="height:300px" type="convo" type-id="{{some_prop}}"></conversation>
    

    I'd like it to be smart enough to refresh the directive when $scope.some_prop changes, as that implies it should show completely different content.

    I have tested it as it is and nothing happens, the linking function doesn't even get called when $scope.some_prop changes. Is there a way to make this happen ?

  • Eno
    Eno about 9 years
    Im working on a similar problem as the OP. The AngularJS docs imply that using = in scope: creates a two-way binding, i.e. changes in child scope propagate up to parent scope and vice versa - is this not the case? I need to be able to tell a directive to update itself from the parent controller.
  • JMK
    JMK about 9 years
    @Eno Did you figure this out? Really confusing me!
  • Eno
    Eno about 9 years
  • Léon Pelletier
    Léon Pelletier over 8 years
    Is it harmful to have the scope of 10000+ directives launching a scope.$watch to listen for a bool to refresh?
  • Micky
    Micky over 6 years
    I found that if the parameter is using '=', the solution above doesn't work, and I'm investigating on it..