AngularJS - 如何强制使用范围,以更新(数组项承诺) [英] AngularJS - how to force a scope to update (promise for array item)
问题描述
我创建了一个角控制器,看起来像这样(编辑为简洁起见):
I've created a controller in Angular that looks like this (edited for brevity):
function AppCtrl($scope, $http, $location, $dataService) {
$scope.projects = $dataService.data.projects;
}
哪个正确加载从我的 $的DataService
服务 $ scope.projects
的承诺。
app.service('$dataService', function($q, $http, $location, $rootScope) {
var dataService = this; //Provides access 'this' inside functions below
var projectsDeferred = $q.defer();
$http.get('/api').success(function(data, status, headers, config) {
projectsDeferred.resolve(data.projects);
}).error(function(err) {
projectsDeferred.reject(err);
});
this.data = {projects: projectsDeferred.promise};
//UPDATE FUNCTION
function updateObjectInArray(array, object, newData) {
for(i in array) {
if(array[i] == object) {
if(newData != undefined) {
array[i] = newData;
} else {
return array[i];
}
}
}
return undefined;
}
this.updateProject = function(project, updateData) {
$http.put('/api/projects/' + project._id, updateData)
.success(function(data, status, headers, config) {
updateObjectInArray(dataService.data.projects.$$v, project, data);
}).error(function(data, status, headers, config) {});
};
});
我已经创造了另一个控制器,它看起来像这样,那选择从项目基于当前URL的数组中的单个项目:
I've created another controller that looks like this, that selects a single project from the array of projects based on the current URL:
function ProjectCtrl($scope, $route) {
//Getting the current project from the array of projects
$scope.project = $scope.projects.then(function(projects) {
for(i in projects) {
if(projects[i]._id == $route.current.params.projectId) {
return projects[i];
}
}
});
}
当我尝试运行我的 updateObjectInArray()
功能(在我的 $ http.put()
要求),我的 $ scope.projects
在 AppCtrl
正确更新(项目的数组),但我的 $ scope.project
在 ProjectCtrl
为不可以更新。我可以登录数组[我]
的 updateObjectInArray()
函数中,它会记录正是我的期望,我可登录 $ scope.projects
在 AppCtrl
,它会相应地更新,但是当我尝试登录 $ scope.project
在我的 ProjectCtrl
控制器,它的不是相应的更新。
When I try to run my updateObjectInArray()
function (on the success of my $http.put()
request), my $scope.projects
in AppCtrl
is correctly updated (the array of projects) but my $scope.project
in ProjectCtrl
is not updated. I can log array[i]
inside the updateObjectInArray()
function and it will log exactly what I expect, and I can log $scope.projects
in AppCtrl
and it will update accordingly, but when I try to log $scope.project
in my ProjectCtrl
controller, it isn't updated accordingly.
我认为的原因是因为我不得不打电话 $ rootScope。$适用()
或 $ rootScope。$摘要()
后,我更新了数组[我]
对象 updateObjectInArray()
,但是,我得到的错误该 $消化正在进行中
。
I thought the reason was because I had to call $rootScope.$apply()
or $rootScope.$digest()
after I updated the array[i]
object in updateObjectInArray()
, however, I get the error that $digest is already in progress
.
什么我需要做,以确保阵列中的我的 $ scope.project
项目获取我的 ProjectCtrl $ C $更新C>?我需要解决一个新的承诺呢?
What do I need to do to make sure my $scope.project
item in the array gets updated in my ProjectCtrl
? Do I need to resolve a new promise for it?
推荐答案
一旦项目
被加载,你使用该数组中的项目之一项目[I]
,让我们从理论上假设它是在内存中的对象为0x1
。问题是,当一个新的项目被加载(假设 0X2
),并更新数组,你改变驻留在阵列位置对象(为0x1
),但 $ scope.project
仍引用现在被遗弃的对象为0x1
。你不能只是改变它在阵列中,您必须修改它,所以你不需要重新绑定 $ scope.project
变量。
As soon as the projects
are loaded, you're using one of the items from the array projects[i]
, let's theoretically assume it's the object 0x1
in memory. The problem is that when a new item is loaded (let's assume 0x2
), and you update the array, you're changing the object that resides in the array position (the 0x1
), but $scope.project
still references the now abandoned object 0x1
. You can't just change it in the array, you have to modify it, so you don't need to rebind the $scope.project
variable.
最好的办法是为更改 数组[我] = newData code> 以
角.extend(数组[我],newData)
。这样,你会只需要改变阵列[我]的所有属性,并为你的 $ scope.project
指向内存中的同一个对象会被更新。
The best solution is to change array[i] = newData
to angular.extend(array[i], newData)
. This way, you gonna just change all properties of array[i], and as your $scope.project
points to the same object in memory it will be updated.
反正,我也相信你可能想的更改 如果(阵列[我] ==对象){
以 如果(阵列[我] ._ ID === object._id){
和您的相等比较( ==
)的到的严格相等比较( ===
)的。这如果
更适合您的事业,为新创建的对象是不一样的旧的。
Anyway, I also believe you may want to change if(array[i] == object) {
to if(array[i]._id === object._id) {
and your equality comparisons (==
) to strictly equality comparisons (===
). This if
suits better your cause, as the new created object is not the same as the old one.
这篇关于AngularJS - 如何强制使用范围,以更新(数组项承诺)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!