简体   繁体   English

参数更改时刷新角度指令

[英]Angular Directive refresh on parameter change

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. 我希望它足够聪明,可以在$scope.some_prop更改时刷新指令,因为这意味着它应该显示完全不同的内容。

I have tested it as it is and nothing happens, the linking function doesn't even get called when $scope.some_prop changes. 我已经对其进行了测试,并且没有任何反应,当$scope.some_prop更改时,甚至没有调用链接函数。 Is there a way to make this happen ? 有没有办法做到这一点?

Link function only gets called once, so it would not directly do what you are expecting. Link函数仅被调用一次,因此它不会直接执行您期望的操作。 You need to use angular $watch to watch a model variable. 您需要使用angular $watch来监视模型变量。

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 如果您不使用隔离范围,请在some_prop上使用watch

What you're trying to do is to monitor the property of attribute in directive. 您想要做的是监视指令中的attribute属性。 You can watch the property of attribute changes using $observe() as follows: 您可以使用$ observe()监视属性更改的属性,如下所示:

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: 如果您有模型,则需要将“ 编译 ”功能更改为“ 链接 ”或使用“ 控制器 ”,并监视模型更改的属性,则应使用$ watch() ,并使用有角的{{}}属性中的括号,例如:

<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);

    }
  };
});

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>
angular.module('app').directive('conversation', function() {
    return {
        restrict: 'E',
        link: function ($scope, $elm, $attr) {
            $scope.$watch("some_prop", function (newValue, oldValue) {
                  var typeId = $attr.type-id;
                  // Your logic.
            });
        }
    };
}

If You're under AngularJS 1.5.3 or newer, You should consider to move to components instead of directives. 如果您使用的是AngularJS 1.5.3或更高版本,则应考虑移至组件而不是指令。 Those works very similar to directives but with some very useful additional feautures, such as $onChanges(changesObj), one of the lifecycle hook, that will be called whenever one-way bindings are updated. 它们的工作原理与指令非常相似,但是具有一些非常有用的附加功能,例如$ onChanges(changesObj)(生命周期挂钩之一),每当单向绑定更新时就会调用它。

app.component('conversation ', {
    bindings: {
    type: '@',
    typeId: '='
    },
    controller: function() {
        this.$onChanges = function(changes) {
            // check if your specific property has changed
            // that because $onChanges is fired whenever each property is changed from you parent ctrl
            if(!!changes.typeId){
                refreshYourComponent();
            }
        };
    },
    templateUrl: 'conversation .html'
});

Here's the docs for deepen into components. 这是用于深入了解组件的文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM