我正在尝试使用AngularJS 1.3(我刚刚从1.2迁移了我的应用)。我正在玩新的一次性绑定。我遇到过这种不起作用的情况,有人可以解释一下原因吗?我通过调用视图中的方法动态生成id字段。结果,一次性绑定似乎不起作用。见http://plnkr.co/edit/GyfKKb?p=preview。
具体来说,我希望在将新元素添加到数组时,一次性不会重新呈现ng-repeat
。但是将新元素推入数组(通过按钮单击)也会使新元素出现在ng-repeat
的输出中。
的index.html
<body ng-controller="MainCtrl">
<!-- TODO: I would expect addItemC() to do nothing with one time binding -->
<button ng-click="addItemC()">add</button>
<div ng-repeat="itemC in ::itemsC">
<!-- dynamically generate id that is cause breakage -->
{{::itemC.id() | limitTo:3}}
</div>
</div>
app.js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
// generate random string id dynamically (code taken from stackoverlow answer)
var itemObj = {
id: function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 100; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
};
// one time binding does not work
$scope.itemsC = [
angular.copy(itemObj),
angular.copy(itemObj),
angular.copy(itemObj)
];
$scope.addItemC = function() {
$scope.itemsC.push(angular.copy(itemObj));
}
});
答案 0 :(得分:2)
我认为这是因为ng-repeat angular内的$ digest循环次数超出抛出误差。主要是因为for循环运行每个项目100次迭代。
如果更改逻辑以在控制器内生成id,然后将项目赋予ng-repeat以进行渲染,那么它可以正常工作。看看我的plunkr
演示 http://plnkr.co/edit/4nFtOy1uGtDyUEWXCVbT?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
// generate random string id dynamically (code taken from stackoverlow answer)
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 100; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function getItem () {
return {
id: makeid()
};
}
var itemObj = {
id: makeid()
};
// one time binding does not work
$scope.itemsC = [
getItem(),
getItem(),
getItem(),
];
$scope.addItemC = function() {
$scope.itemsC.push(getItem());
}
$scope.removeItem = function(item) {
var index = $scope.itemsC.indexOf(item);
$scope.itemsC.splice(index, 1);
}
});
标记内部将itemC.id()
更改为itemC.id
,因为ID现在属性。
答案 1 :(得分:2)
我认为因为你是一次性绑定函数并且每次调用函数。在双花括号内调用函数将给出函数返回的任何内容。通过保持返回随机字符串,函数保持不变。
因此,一次性绑定实际上可以通过保持调用相同的函数来实现。请注意,该功能不会更改。我添加了一个新属性,它不是对象的一个函数,以显示一次绑定实际工作。
<div style="font-weight:bold;">itemsC:</div>
<div ng-repeat="itemC in ::itemsC">
<div ng-click="removeItem(itemC)">
<!-- dynamically generate id -->
{{::itemC.name | limitTo:3 }}
</div>
</div>
<div style="margin-top:10px;">{{itemsC}}</div>