【问题标题】:Angular directive watch variable not triggering角度指令监视变量未触发
【发布时间】:2015-01-13 23:36:31
【问题描述】:

首先,这里是code

app.controller('MainCtrl', function($scope) {
  $scope.test="Hello!";
  $scope.updateFlag = false;
  function updateFunc(){
    $scope.updateFlag = true;
  }
  $scope.updateFunc = updateFunc;

});



app.directive('dir1', function(){
  return {
    scope:{
      updateFunc:'='
    },
    link: function(scope,element,attr,ctrl){
      element.bind('click', scope.updateFunc);
    }
  }
});

app.directive('dir2', function(){
  return {
    template: '{{privateVal}}',
    scope:{
      updateFlag:'='
    },
    link: function(scope,element,attr,ctrl){
      scope.privateVal= "Not working!";
      scope.$watch(scope.updateFlag, function(newval, oldval){
        alert("watch triggered");
        if (newval===true){
          scope.privateVal = "Worked!!";
        }
      })
    }
  }
});

我有 2 个指令,1 个带有 2 路绑定到全局函数,另一个正在监视全局函数正在更改的全局变量。但是,不知何故,当全局函数被调用时,我的监视函数没有被触发。非常感谢任何帮助。

谢谢,

【问题讨论】:

  • 尝试用返回scope.updateFlag的函数替换$watch的第一个参数。或者改成字符串。
  • 刚刚做了,还是不行
  • 如果您有一些用于指令的全局模块 - 不要忘记将您的 Directive 类添加到模块的导出/声明部分

标签: javascript angularjs angularjs-directive angularjs-scope


【解决方案1】:

如果您不想使用此超时选项执行此操作,还有其他几种方法可以解决此问题,我认为它们有一些优势:

1.) 不要使用隔离范围。刚刚从控制器调用方法:

<button dir1 ng-click="updateFunc()">Click me!</button>

2.) 使用隔离作用域,仍然使用 ng-click,但像这样:http://plnkr.co/edit/TrahxB

您将函数作为属性传入。使用 & 的绑定模式并从范围对象中获取它。你看我把它叫做“更新”,然后在指令中用 ng-click=update() 运行它。这还允许您将数据从指令传递到对象映射中的控制器,这在您构建时可能很有用!
Here is a great tutorial to explain this.

或者,如果您想要一个隔离范围的指令,但不需要隔离该函数,您可以将所有点击逻辑放在 DOM 中,然后将其转换到指令中 - 使用 #1 中的策略。嵌入的 dom 元素在父级的控制器范围内 - see this

3.) 使用隔离作用域,您可以在指令上使用 ng-click 来调用该指令与 Emit an event to be watched on the controller. 的链接函数上的函数

【讨论】:

    【解决方案2】:

    因为您正在调用本机点击事件,所以不会调用 digest 循环。 使用$timeout解决:

    app.directive('dir1', function($timeout){
      return {
        scope:{
          updateFunc:'='
        },
        link: function(scope,element,attr,ctrl){
          element.bind('click', function()
          {
            $timeout(scope.updateFunc)
          });
        }
      }
    });
    

    http://plnkr.co/edit/ReqExBvlPuRL5vp7WJ0y?p=preview

    【讨论】:

    • 使用scope.$apply() 比使用$timeout 更好
    • @NewDev scope.$apply() 如果已经在进行中,可能会给您错误。 $timeout 检查是否已经在进行中,然后调用 $apply()。见 - stackoverflow.com/a/18996042/3191896
    • 在这种情况下,如果我理解正确的话,摘要不应该是“正在进行中”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    相关资源
    最近更新 更多