我有时会对AngularJS有严重的麻烦。所以我的控制器中有一个基本数组,如
$scope.items = ["a","b","c"]
我正在我的模板中重复项目数组ng-repeat =“item in items”。到目前为止超级直播。经过几次UX操作后,我想将一些新东西推送到我的阵列。
$scope.items.push("something");
因此,50%的时间,新元素被添加到视图中。但其他50%,没有任何反应。这就像超级沮丧; bc如果我把它包装在$ scope。$ apply()中,我得到了“$ digest in progress”错误。将其包装到$ timeout也无济于事。
当我使用Chrome扩展程序检查我的元素范围时;我可以看到新数据存在且$ scope.items值是正确的。但是视图并没有考虑将其添加到DOM中。
谢谢!
答案 0 :(得分:21)
您正在50%的时间内在范围$digest
周期之外修改范围。
如果有回调不是来自angularjs; (可能是jquery)。您需要致电$apply
以强制进行$digest
周期。
但是,您无法在$apply
周期内拨打$digest
,因为您所做的每项更改都会自动反映出来。
您需要知道回调何时不是来自角度,并且应该仅在此时调用$apply
。
如果您不知道并且无法学习,这是一个巧妙的技巧:
var applyFn = function () {
$scope.someProp = "123";
};
if ($scope.$$phase) { // most of the time it is "$digest"
applyFn();
} else {
$scope.$apply(applyFn);
}
答案 1 :(得分:4)
正如UmurKontacı所指出的,你有时会在摘要周期之外进行模型更改。但是,我建议您确保不会发生这种情况,而不是解决此问题并尝试检测您是否处于应用/摘要上下文中。
此问题的主要原因是您的函数被调用为对DOM事件的反应。 E.g。
jQuery('.some-element').click(function() { seeminglyProblematicCode() })
这是你的$ apply()需要去的地方,而不是在函数内。否则,您的整个代码迟早会被这些区别所困扰。假设在此事件处理程序的上下文中有一个范围,您可以编写:
jQuery('.some-element').click(function() {
$scope.$apply(function() { seeminglyProblematicCode() })
})
但是,您必须注意一个警告:当您从代码中触发单击事件时,您将遇到摘要周期已在进行中的问题。这是你需要$ timeout的地方。 ApnsServiceBuilder withProxy(java.net.Proxy)的答案很好地解决了这个问题。
答案 2 :(得分:0)
我遇到了同样的问题,我的修复方法是观察在嵌套指令中调用哪些控制器。
# Parent Controller
app.controller 'storeController', ($scope, products) ->
$scope.cart = ["chicken", "pizza"]
$scope.addToCart = (item) ->
$scope.cart.push item
# from service
products.get().then (items) ->
$scope.products = items
# Parent Directives
app.directive 'storeContainer', ($scope, config) ->
restrict: 'E'
templatUrl: 'store-container.html'
controller: 'storeController'
# Nested Directive
app.directive 'storeFront', ($scope, config) ->
restrict: 'E'
templatUrl: 'store-front.html'
controller: 'storeController'
# Parent Template templates/directives/store-container.html
<div ng-repeat="item in cart">{{ item }}</div>
<strore-front></store-front>
# Nested Template templates/directives/store-front.html
<ul ng-repeat="item in products">
<li ng-click"addToCart(item)">{{ item }}</li>
</ul>
这里的错误是嵌套指令在原型链中创建第二个控制器(storeController的副本),父模板无权访问。解决方案如下所示写嵌套控制器:
# Nested Directive
app.directive 'storeFront', ($scope, config) ->
restrict: 'E'
templatUrl: 'store-front.html'
有更好的方法来创建继承链,但这将解决许多人学习AngularJS的问题。