【问题标题】:Controller scope object changes not reflected in directive $watch callback控制器范围对象更改未反映在指令 $watch 回调中
【发布时间】:2013-12-11 13:36:43
【问题描述】:

我有一个控制器,它的作用域上有一个对象:$scope.objToTrack。 我有一个位于嵌套视图中的指令,该指令 $watches 以查看对该对象的更改。
它具有隔离作用域,但将objToTrack 设置为= 以便可以观看。

当我单击该指令时,它会调用一个表达式,该表达式是控制器上更改objToTrack 的方法。

这是一个 plunker 来说明我的设置。

问题是objToTrack $watch 回调没有被触发,尽管对象被改变了。
如果在 Test1 和 Test2 状态之间切换,对 objToTrack 所做的更改是可见的。只是我不明白为什么它不能在点击时立即起作用。

谢谢。

【问题讨论】:

  • 指令范围在演示中未设置为=。也很好奇为什么不使用ng-click 而不是自己的事件处理程序。每当您使用外部事件处理程序更改范围或角度不知道更改时,都必须使用$apply
  • 代码 sn-p 是一个演示,real 指令的作用远不止这些。

标签: angularjs angular-ui-router


【解决方案1】:

要回答问题...如果您将自己的事件处理程序绑定到一个元素,并在该事件处理程序内更改角度范围,您需要调用 $apply 以便 Angular 了解更改并可以运行摘要

例如你有:

element.on('click',function(){
       scope.onClick({number:RNG.int(200,300)});
});

需要改成:

element.on('click',function(){
    scope.$apply(function(){
        scope.onClick({number:RNG.int(200,300)});
     });
});

如果你使用 angular 已经提供的事件指令会简单很多。在这种情况下,与使用 ng-click 相比,您正在编写大量额外代码。当您尽可能保持在角度范围内时,它还可以使测试变得更加容易

【讨论】:

  • plunkr 可以与 $apply 一起使用,但我正在开发的应用程序不能。这很奇怪。尤其是如果我使用 @ 而不是 = 我会在指令中获得实时更新。
  • 不要认为jQuery 喜欢方法...只需使用ng-clcik。让 Angular 处理 DOM
  • 这与jQuery无关。在调用控制器上的方法之前,该指令会在点击时触及 DOM。 Plunkr 大大简化了。
  • 不,我的意思是大多数时候不需要添加自己的事件处理程序
  • 我同意,但是我必须将数据传递给控制器​​方法,我不确定我是否可以使用 ngClick 来做到这一点。
【解决方案2】:

另外,如果你想将一个对象传递给你的指令,你不应该使用花括号。 在 html 中,使用obj-to-track="objToTrack",而不是obj-to-track="{{objToTrack}}"。 像这样:

<div simple-directive obj-to-track="objToTrack" class="directive"></div>

在directive.js 中:使用'=' 来双向绑定objToTrack。 像这样:

scope:{
  objToTrack:'='
}

【讨论】:

  • 那是一个错误,我给了错误的链接。我正在使用不带花括号的=
【解决方案3】:

在“test*.html”文件中,将“on-click”替换为“ng-click”。

“on-click”不会在您当前的控制器中查找,“ng-click”会。

【讨论】:

  • 指令已经将onClick 传递到隔离范围内,因此它是可用的。区别更多的是与$apply 不需要用ng-clcik 调用
猜你喜欢
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-17
相关资源
最近更新 更多