将新对象“附加”到 ng 重复项
"Attach" a new object to a ng-repeated item
我有一个items
循环,需要通过API动态替换。问题在于,外部范围在替换原始对象时似乎失去了对原始对象的引用。如何使外部作用域注意到数组中某个项的值更改?
(function(ng) {
'use strict';
ng.module('app', [])
.controller('ParentController', ['$scope',
function($scope) {
$scope.items = [{
name: "Foo",
number: 0
}, {
name: "Bar",
number: 1
}, {
name: "Baz",
number: 1
}];
}
])
.controller('ItemController', ['$scope',
function($scope) {
// fake code, would get from API normally
var getFromApi = function() {
return {
name: $scope.item.name,
number: $scope.item.number + 1
};
}
$scope.incr = function() {
$scope.item = getFromApi();
}
}
]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<body ng-app="app">
<div ng-controller="ParentController">
<p>When you click one of the below buttons</p>
<ul>
<li ng-repeat="item in items" ng-controller="ItemController">
{{item.name}} ({{item.number}})
<button ng-click="incr()">+</button>
</li>
</ul>
<p>This should update</p>
<p>{{items}}</p>
<p>...but it doesn't</p>
</div>
</body>
</html>
您需要知道要更改其属性的项的键,然后在集合中更改此项。
要声明密钥,您可以使用ng-repeat="(key, item) in items"
.然后,该密钥将作为$scope.key
在ItemController
中提供。
接下来,由于ItemController
继承了$scope
ParentController
,您可以直接访问ItemController
中的$scope.items
:
项目控制器.js:
$scope.incr = function() {
$scope.items[$scope.key] = getFromApi();
}
仅当 ItemController 是父控制器的子级或继承其作用域时,这才有可能。
您可以看到脚本像这样运行:
(function(ng) {
'use strict';
ng.module('app', [])
.controller('ParentController', ['$scope',
function($scope) {
$scope.items = [{
name: "Foo",
number: 0
}, {
name: "Bar",
number: 1
}, {
name: "Baz",
number: 1
}];
}
])
.controller('ItemController', ['$scope',
function($scope) {
// fake code, would get from API normally
var getFromApi = function() {
return {
name: $scope.item.name,
number: $scope.item.number + 1
};
}
$scope.incr = function() {
$scope.items[$scope.key] = getFromApi();
}
}
]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<body ng-app="app">
<div ng-controller="ParentController">
<p>When you click one of the below buttons</p>
<ul>
<li ng-repeat="(key, item) in items" ng-controller="ItemController">
{{item.name}} ({{item.number}})
<button ng-click="incr()">+</button>
</li>
</ul>
<p>This updates</p>
<p>{{items}}</p>
<p>...and it does!</p>
</div>
</body>
</html>
您可以使用父数组中项的索引来替换它
(function(ng) {
'use strict';
ng.module('app', [])
.controller('ParentController', ['$scope',
function($scope) {
$scope.items = [{
name: "Foo",
number: 0
}, {
name: "Bar",
number: 1
}, {
name: "Baz",
number: 1
}];
}
])
.controller('ItemController', ['$scope',
function($scope) {
// fake code, would get from API normally
var getFromApi = function() {
return {
name: $scope.item.name,
number: $scope.item.number + 1
};
}
$scope.incr = function() {
$scope.$parent.items[$scope.$index] = getFromApi();
}
}
]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<body ng-app="app">
<div ng-controller="ParentController">
<p>When you click one of the below buttons</p>
<ul>
<li ng-repeat="item in items track by $index" ng-controller="ItemController">
{{item.name}} ({{item.number}}) {{$index}}
<button ng-click="incr()">+</button>
</li>
</ul>
<p>This should update</p>
<p>{{items}}</p>
<p>...but it doesn't</p>
</div>
</body>
</html>
另一个(hacky)选项是简单地遍历新对象,分配旧对象的变量:
var newItem = getFromApi();
for (var key in newItem) {
$scope.item[key] = newItem[key];
}
(function(ng) {
'use strict';
ng.module('app', [])
.controller('ParentController', ['$scope',
function($scope) {
$scope.items = [{
name: "Foo",
number: 0
}, {
name: "Bar",
number: 1
}, {
name: "Baz",
number: 1
}];
}
])
.controller('ItemController', ['$scope',
function($scope) {
// fake code, would get from API normally
var getFromApi = function() {
return {
name: $scope.item.name,
number: $scope.item.number + 1
};
}
$scope.incr = function() {
var newItem = getFromApi();
for (var key in newItem) {
$scope.item[key] = newItem[key];
}
}
}
]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html>
<body ng-app="app">
<div ng-controller="ParentController">
<p>When you click one of the below buttons</p>
<ul>
<li ng-repeat="item in items" ng-controller="ItemController">
{{item.name}} ({{item.number}})
<button ng-click="incr()">+</button>
</li>
</ul>
<p>This should update</p>
<p>{{items}}</p>
<p>...now it does!</p>
</div>
</body>
</html>
您可以将 API 调用逻辑移动到父控制器,请参阅 JSFiddle 演示以获取示例,或者至少替换父作用域$scope.items
数组中修改的元素。
编辑:在这里废弃我之前的陈述,它不起作用的 reson 是因为当您在子作用域的 incr()
方法中分配$scope.item
时,您没有修改$scope.items
数组。您只是在子作用域中更改变量赋值。
因此,在incr()
调用之前,内存中的变量赋值可能如下所示:
$scope.items =
item1 -> [ js obj 1 ]
item2 -> [ js obj 2 ]
item3 -> [ js obj 3 ]
$scope.item -> [ js obj 1 ]
在incr()
呼叫第一项之后:
$scope.items =
item1 -> [ js obj 1 ] // still obj 1 here!
item2 -> [ js obj 2 ]
item3 -> [ js obj 3 ]
$scope.item -> [ js obj 4 ] // but entirely new obj here!
示例代码:
angular.module('app', [])
.controller('ParentController', ['$scope',
function ($scope) {
$scope.items = [{
name: "Foo",
number: 0
}, {
name: "Bar",
number: 1
}, {
name: "Baz",
number: 1
}];
// fake code, would get from API normally
var getFromApi = function (item) {
return {
name: item.name,
number: item.number + 1
};
}
$scope.updateItem = function (index) {
$scope.items[index] = getFromApi($scope.items[index]);
};
}])
.controller('ItemController', ['$scope',
function ($scope) {
$scope.incr = function (index) {
$scope.updateItem(index);
}
}]);
显然,如果您想以另一种方式识别修改后的项目,您可以在不使用$index
的情况下逃脱。上面的代码只是针对您的问题的最简单的修复方法。您可能会将getFromApi()
保留在子作用域中,并仅在那里使用$scope.items[$index] = getFromApi()
(由于作用域继承)。我只是发现将该方法保留在父范围内更干净。
- ng映射方向备选方案
- 表追加而不附加最后一个元素
- AngularJS UI路由器不能像ng路由器那样工作
- 如果ng单击附加到提交按钮,则表单未验证
- 将新对象“附加”到 ng 重复项
- 可以将ng模型附加到样式标记吗
- ng隔离未附加到templateUrl的作用域
- ng.在角度中检查.js不使用HTML附加
- AngularJS - 使用 ng-include 附加 html
- 如何在 ng-repeat 中将变量值附加到事件调用
- AngularJS ng-click不适用于动态附加的剑道面板栏
- 通过指令附加angularjs控制器不会分配class=“ng-scope”
- 如何使用附加到html标签的嵌套ng应用程序将一个基于angularjs的SPA包含到另一个基于angularjs
- 为什么我不能将ng-click附加到我的元素
- 为什么Angular要把ng-scope类放在一个没有附加作用域的元素上?
- 附加Html代码中的Angular ng-model不起作用
- 在ng-click时附加模板
- AngularJS -在ng-repeat中向单个项附加HTML
- 将d3 svg附加到当前的ng-repeat元素
- ng 单击不起作用新附加的元素