【问题标题】:Angular Directive refresh on parameter change角度指令刷新参数更改
【发布时间】:2014-01-18 08:36:50
【问题描述】:

我有一个 angular 指令,它的初始化如下:

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

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

我已经对其进行了测试,但没有任何反应,当$scope.some_prop 更改时,链接函数甚至不会被调用。有没有办法做到这一点?

【问题讨论】:

    标签: javascript angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    如果您使用的是 AngularJS 1.5.3 或更新版本,您应该考虑使用组件而不是指令。 这些工作方式与指令非常相似,但具有一些非常有用的附加功能,例如 $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'
    });
    

    这里是docs,用于深入了解组件。

    【讨论】:

      【解决方案2】:

      我希望这将有助于重新加载/刷新父范围值的指令

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

      【讨论】:

        【解决方案3】:

        您要做的是监视指令中属性的属性。您可以使用 $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);
        
            }
          };
        });
        

        请记住,我在这里的指令中使用了“编译”功能,因为您没有提到您是否有任何模型以及这是否对性能敏感。

        如果您有模型,则需要将 'compile' 功能更改为 'link' 或使用 'controller' 并监控模型的属性发生变化,您应该使用 $watch(),并从属性中取出角 {{}} 括号,例如:

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

        在指令中:

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

        【讨论】:

          【解决方案4】:
          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.
                      });
                  }
              };
          }
          

          【讨论】:

            【解决方案5】:

            Link 函数只被调用一次,因此它不会直接执行您所期望的操作。您需要使用 angular $watch 来观察模型变量。

            此手表需要在链接功能中设置。

            如果你对指令使用隔离作用域,那么作用域就是

            scope :{typeId:'@' }

            在你的链接功能中,然后你添加一个手表

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

            如果您不使用隔离作用域,请在 some_prop 上使用 watch

            【讨论】:

            • 我正在解决与 OP 类似的问题。 AngularJS 文档暗示在scope: 中使用= 创建双向绑定,即子作用域的更改传播到父作用域,反之亦然——不是这样吗?我需要能够告诉指令从父控制器更新自身。
            • @Eno 你知道了吗?真的让我很困惑!
            • 让 10000 多个指令的范围启动一个 scope.$watch 来监听 bool 刷新是否有害?
            • 我发现如果参数使用'=',上面的解决方案不起作用,我正在研究它..
            猜你喜欢
            • 1970-01-01
            • 2015-04-30
            • 2015-12-14
            • 2016-03-24
            • 2020-02-17
            • 2017-10-26
            • 2015-06-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多