Javascript &引用;附「;将新对象添加到重复项
我有一个Javascript &引用;附「;将新对象添加到重复项,javascript,angularjs,Javascript,Angularjs,我有一个项循环,需要通过API动态替换。问题是,外部范围在被替换时似乎失去了对原始对象的引用。如何使外部作用域注意到数组中某个项的值的变化 (功能(ng){ "严格使用",; ng.模块('应用程序',[]) .controller('ParentController',['$scope', 职能($范围){ $scope.items=[{ 姓名:"富",, 编号:0 }, { 名称:“酒吧”, 编号:1 }, { 名称:“Baz”, 编号:1 }]; } ]) .controller('It
项循环
,需要通过API动态替换。问题是,外部范围在被替换时似乎失去了对原始对象的引用。如何使外部作用域注意到数组中某个项的值的变化
(功能(ng){
"严格使用",;
ng.模块('应用程序',[])
.controller('ParentController',['$scope',
职能($范围){
$scope.items=[{
姓名:"富",,
编号:0
}, {
名称:“酒吧”,
编号:1
}, {
名称:“Baz”,
编号:1
}];
}
])
.controller('ItemController',['$scope',
职能($范围){
//伪代码,通常从API获取
var getFromApi=函数(){
返回{
名称:$scope.item.name,
编号:$scope.item.number+1
};
}
$scope.incr=函数(){
$scope.item=getFromApi();
}
}
]);
})(窗口角度)代码>
当您单击以下按钮之一时
-
{{item.name}}({{item.number})
+
这应该更新
{{items}}
……但事实并非如此
您需要知道要更改其属性的项目的键,然后在集合中更改此项目
要声明密钥,可以使用ng repeat=“(密钥,项)in items”
。然后,该键将作为ItemController
中的$scope.key
可用
接下来,由于ItemController
从ParentController
继承了$scope
,您可以直接访问ItemController
中的$scope.items
:
ItemController.js:
$scope.incr = function() {
$scope.items[$scope.key] = getFromApi();
}
只有当ItemController是ParentController的子项或继承了它的作用域时,才可能执行此操作。
您可以看到脚本如下运行:
(功能(ng){
"严格使用",;
ng.模块('应用程序',[])
.controller('ParentController',['$scope',
职能($范围){
$scope.items=[{
姓名:"富",,
编号:0
}, {
名称:“酒吧”,
编号:1
}, {
名称:“Baz”,
编号:1
}];
}
])
.controller('ItemController',['$scope',
职能($范围){
//伪代码,通常从API获取
var getFromApi=函数(){
返回{
名称:$scope.item.name,
编号:$scope.item.number+1
};
}
$scope.incr=函数(){
$scope.items[$scope.key]=getFromApi();
}
}
]);
})(窗口角度)代码>
当您单击以下按钮之一时
-
{{item.name}}({{item.number})
+
此更新
{{items}}
…的确如此
您可以使用父数组中项目的索引来替换它
(功能(ng){
"严格使用",;
ng.模块('应用程序',[])
.controller('ParentController',['$scope',
职能($范围){
$scope.items=[{
姓名:"富",,
编号:0
}, {
名称:“酒吧”,
编号:1
}, {
名称:“Baz”,
编号:1
}];
}
])
.controller('ItemController',['$scope',
职能($范围){
//伪代码,通常从API获取
var getFromApi=函数(){
返回{
名称:$scope.item.name,
编号:$scope.item.number+1
};
}
$scope.incr=函数(){
$scope.$parent.items[$scope.$index]=getFromApi();
}
}
]);
})(窗口角度)代码>
当您单击以下按钮之一时
-
{{item.name}{{{item.number}}{{$index}}
+
这应该更新
{{items}}
……但事实并非如此
您可以将API调用逻辑移动到父控制器,请参见示例,或者至少替换父范围中的$scope.items
数组中修改的元素
EDIT:在这里废弃我以前的语句,它不起作用的原因是当您在子作用域的incr()
方法中分配$scope.items
时,您没有修改$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()
(由于作用域继承)。我只是觉得将该方法保持在父范围内更干净。另一个(hacky)选项是简单地循环新对象,分配旧对象的变量:
var newItem = getFromApi();
for (var key in newItem) {
$scope.item[key] = newItem[key];
}
(功能(ng){
"严格使用",;
ng.模块('应用程序',[])
.controller('ParentController',['$scope',
职能($范围){
$scope.items=[{
姓名:"富",,
编号:0
}, {
名称:“酒吧”,
编号:1
}, {
名称:“Baz”,
编号:1
}];
}
])
.controller('ItemController',['$scope',