【问题标题】:angularJS element.on callback and scope.$applyangularJS element.on 回调和 scope.$apply
【发布时间】:2013-12-12 23:46:11
【问题描述】:

在这个例子中,我有一个带有附加指令的输入。该指令旨在在输入旁边显示消息。还有另一个输入和一个按钮来添加消息。 一旦显示了一些消息,关注带有附加指令的输入应该会清除这些消息。 http://jsfiddle.net/viro/WBqxf/

所以我有一个带有独立模型的指令,并且当具有该指令的元素成为焦点时,我正在尝试更新模型。 看来我必须在范围内包装事件回调。如果我想更新模型,$apply:

element.on('focus',function(){
    scope.$apply(function(){
        console.log("focus !");
        scope.tstMsg=[];
    })
});

我想我必须将它包装在 $apply 中,因为我使用的是 jqlite 事件回调,并且我猜它们在“外部”angularJS 运行,但我没有在文档中明确说明。

我做得对吗?

有没有更好的方法?

【问题讨论】:

  • 使用 ng-focus 并为外部事件处理程序节省额外的编码 docs.angularjs.org/api/ng.directive:ngFocus
  • 但是对于每个附加了指令的元素,我希望在焦点上具有相同的行为,而不管元素所在的控制器。使用 ngFocus,我必须为每个元素创建一个重置消息数组的函数,如果它可以由指令自动执行,那会很乏味,不是吗?

标签: angularjs angularjs-directive jqlite angularjs-model


【解决方案1】:

每当您使用第三方库并执行更改时,您需要通过调用 $apply() 让 Angular 知道。

正如@charlietfl 提到的,ng-focus 更容易:

控制器

$scope.focus = function() {
    // Do something
}

HTML

<input ng-model="inp" tst-msg="message" ng-focus="focus()" />

jsFiddle

【讨论】:

  • 出于某种原因,当我在没有 $apply 的情况下执行此操作时,它将无法正常工作。我必须检查一下。 ng-focus 不是我的解决方案,因为我希望指令能够自给自足。我不想编写一个函数来重置每个控制器的消息,其中我有一个带有指令的输入。
  • 我更新了 jsFiddle(删除了 $apply())并添加了 ng-focus。看一看。如果它只对我有用,我会感到困惑:)
  • 我看了看。确实有效。但是,如果您删除了 ng-focus,则不会。你的例子帮助我理解了一些事情:ng-focus 由 angularJS 处理,它在焦点上做了一个 $digest 循环,所以在这种情况下我不需要在事件回调中这样做。如果我想摆脱 ng-focus,我需要 $apply。
  • @DavidV。好的,这是有道理的:) 有趣的巧合。很抱歉造成混乱。
【解决方案2】:

scope.$apply 将导致 $digest 运行,因此范围内的任何观察者都将检查更改并在适当的情况下触发。因为正如你所说,你只是绑定到一个事件(只是 addEventListener/attachEvent 适当)做范围。$apply 在这种情况下是有效的。

【讨论】:

  • 所以这意味着从 element.on 绑定的回调不是“angularJS 感知”?我不确定。
  • 是的,正如您在问题中所说,因为它只是使用 jqLit​​e 或 jQuery(如果您包含它),它不在角度代码的上下文中。 $http 和 $timeout 之类的服务自动具有范围。$apply 调用
  • 所以,就像有 $timeout 而不是 setTimeout;有什么东西可以代替 element.on 吗?
  • 这里要注意的另一件事,将函数传递给 scope.$apply() 将捕获函数中发生的任何错误,以使用 Angular 错误处理进行处理,如果不需要,您可以运行您的代码,然后调用 scope.$apply。关于绑定到事件的角度服务等,我认为不存在任何东西,有 $on 但这意味着可以与 $broadcast 和 $emit 一起使用,但我认为它与 DOM 事件无关。
猜你喜欢
  • 2014-07-27
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-16
相关资源
最近更新 更多