回调函数到angularjs中的$ apply()?

时间:2014-02-17 22:56:37

标签: angularjs data-binding

我想要做的是将一个对象推送到一个绑定到html的angularjs的数组,然后在新创建的元素上执行click操作。 代码就像这样

$scope.fruits = {"orange", "plum", "cherry"};
$scope.add = function() {
    $scope.fruits.push("apple");
    //this would add an element to the html, then I want to click on the element
    $('#fruits').children.eq(-1).click();//click the last element (which has just been created)
}

html就像:

<div id="fruits">
    <div ng-repeat="fruit in fruits"></div>
</div>

问题是,当一个对象被推送到模型时,angular会像$ scope一样。$ apply()动态更新html。 如果我用.children()。eq(-1).click()单击最后一个元素,它将不会在创建新元素后等待,它实际点击的是“cherry”div。

我尝试在click()之前调用$ scope。$ apply(),它可以工作,但是我收到了以下错误消息:

$apply already in progress

我认为这不是一个好习惯,并且不应该以这种方式调用$ apply()。

1 个答案:

答案 0 :(得分:0)

当您添加到$ scope时,您将进入摘要循环并且DOM将不会被编译和刷新,直到这些循环完成 - 基本上在您的$ scope push中您正在更改数组但是此时渲染的DOM仍然存在有以前的项目。一旦它退出循环,来自转发器的观察者将触发并渲染新的DOM元素,但您已经离开了控制器。

解决方案非常简单。您只需要在当前摘要循环结束时排队更新。您可以使用setTimeout无延迟地执行此操作。这将把你的函数放在队列中并在当前处理完成时调用它:

setTimeout(function() {
   $('#fruits').children().eq(-1).click();
}, 0);

这是一个工作小提琴:http://jsfiddle.net/jeremylikness/bWeQL/

(我强烈建议您考虑为此编写一个指令,以避免直接在控制器内操作DOM)。