AngularJS在更新数组时不刷新ngRepeat
AngularJS not refreshing ngRepeat when updating array
有时候我很难理解AngularJS。控制器中有一个基本数组,比如
$scope.items = ["a","b","c"]
我在我的模板中复制项目数组ng-repeat="item in items"。到目前为止非常简单。在几个UX操作之后,我想把一些新东西推到我的数组中。
$scope.items.push("something");
因此,50%的时间,新元素被添加到视图中。但剩下的50%,什么都没发生。这就像超级令人沮丧;如果我把它包装在$scope.$apply()中,我得到一个"$digest already in progress"的错误。将其封装到$timeout中也没有帮助。
当我检查我的元素范围使用Chrome扩展;我可以看到这里有新的数据和$作用域。"Items"值是否正确。但是视图并没有把它添加到DOM中。
谢谢!
你在50%的时间里在angular的$digest
循环之外修改作用域。
如果有一个不是来自angularjs的回调;(posibbly jquery)。你需要调用$apply
来强制$digest
循环。但是你不能在$digest
循环中调用$apply
,因为你所做的每一个更改都会自动反映出来。
你需要知道什么时候回调不是来自angular,应该只调用$apply
。
如果你不知道也无法学习,这里有一个巧妙的技巧:
var applyFn = function () {
$scope.someProp = "123";
};
if ($scope.$$phase) { // most of the time it is "$digest"
applyFn();
} else {
$scope.$apply(applyFn);
}
正如Umur kontacyi所指出的,您有时会在摘要周期之外进行模型更改。但是,与其解决这个问题并试图检测您是否处于应用/摘要上下文中,我建议您确保这种情况永远不会发生。
这个问题的主要原因是您的函数是作为对DOM事件的响应而调用的。例如
jQuery('.some-element').click(function() { seeminglyProblematicCode() })
这是你的$apply()需要去的地方,而不是在函数中。否则,您的整个代码迟早会充斥着这样的区别。假设在这个事件处理程序的上下文中有一个作用域,您可以这样写:
jQuery('.some-element').click(function() {
$scope.$apply(function() { seeminglyProblematicCode() })
})
然而,有一点需要注意:当您从代码中触发click事件时,您将遇到一个问题,即摘要循环已经在进行中。这就是需要使用$timeout的地方。这个问题的答案很好地涵盖了这个问题。
我也遇到了同样的问题,我的修复方法是观察在嵌套指令中调用了哪些控制器。
# 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的人的问题。
- 强制模板刷新ember.js
- 如何通过ajax刷新JSF填充的javascript变量
- 如何使用ngrepeat和双向绑定获得指令的隔离范围
- 如何解决Yii中的页面刷新问题
- Jquery提交表单而不刷新
- 刷新页面后会出现警报
- 刷新后保留对网页的更改
- 如何在不刷新页面的情况下更新显示框
- 重定向时角度刷新浏览器
- 如何防止jQueryonclick事件中的Ruby方法在页面刷新时执行
- Javascript,输出结果后页面不断刷新
- $(document).height()在刷新时随机化值(Safari 5.1.10)
- 刷新父窗口后无法关闭窗口
- 刷新页面时hasClass不起作用
- X秒后刷新select元素
- chart.series[id].remove()无法刷新高位图表/高位股票中其他系列的图例属性
- 触发媒体查询断点时刷新页面
- 如何刷新列表框内容onclick或blur事件
- AngularJS -在事件发生时刷新ngRepeat数组数据
- AngularJS在更新数组时不刷新ngRepeat