推迟$摘要(提高DOM事件)后angularjs手表执行(Defer angularjs watch

2019-08-31 09:56发布

我有一个触发DOM事件的手表:

scope.$watch(function() { return controller.selected; }, function(selected) {
    if (selected) {
        $input.trigger('focus');
    }
});

问题是,我有,做了“专注”的处理程序scope.$apply

$input.bind('focus', function() {
    scope.$apply(function() { controller.focused = true; });
});

所以,当我的$watch是由内解雇$digest ,因为它试图触发另一个则导致错误出现$digest

解决方法我是把触发器在$timeout

scope.$watch(function() { return controller.selected; }, function(selected) {
    if (selected) {
        $timeout(function() { $input.trigger('focus'); });
    }
});

这个工程......至今。 这是处理这一正确的方法是什么? 我不知道这是否捕捉每一种情况下,想看看是否有一个角批准的方式有一块代码延迟为消化后。

谢谢!

Answer 1:

$超时通常就是用于运行的东西消化周期后(和浏览器呈现 )。

$timeout会造成执行功能之后要执行另一种消化周期。 如果trigger不影响任何角度,你可以设定invokeApply参数false ,以避免在运行其它消化周期。

如果你希望你的回调浏览器呈现之前运行:如果代码是用排队$evalAsync 从一个指令 ,之后DOM已被角操纵它应该运行,但在浏览器呈现前。 但是,如果代码使用排队$evalAsync 从控制器 ,它会之前DOM已被角(之前的浏览器呈现)操作运行。 又见https://stackoverflow.com/a/17303759/215945 。



Answer 2:

就像大家口口声声说,你不应该在你的控制器做DOM的东西。

下面是适用双向数据绑定到集中的解决方案。 现在,你的注意力被绑定到一个变量。 所以,当你的变量设置为true,则设置相应的元素上的焦点,当元素获得焦点的变量。

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

现在,我们已经成功分离从控制器代码的焦点。 它也需要照顾的所有$超时问题(我猜)。 你需要知道的唯一的事情是,你不应该使用相同的变量绑定到两种不同元素的焦点。

编辑:自上次一个wasnt工作正常更新了普拉克。



文章来源: Defer angularjs watch execution after $digest (raising DOM event)