我已经在Angular中创建了一个如下所示的控制器(为简洁起见进行了编辑):
function AppCtrl($scope, $http, $location, $dataService) { $scope.projects = $dataService.data.projects; }
正确加载了$scope.projects我的$dataService服务中的承诺。
$scope.projects
$dataService
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从项目数组中选择一个项目:
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为 不 更新。我可以登录array[i]的内部updateObjectInArray()功能,它会记录正是我期待的,我可以登录$scope.projects的AppCtrl,它会相应地更新,但是当我尝试登录$scope.project我的ProjectCtrl控制器,它 不会 随之更新。
updateObjectInArray()
$http.put()
AppCtrl
$scope.project
ProjectCtrl
array[i]
我以为原因是因为必须调用$rootScope.$apply()或$rootScope.$digest()更新了其中的array[i]对象之后updateObjectInArray(),但是出现的错误$digest is already in progress。
$rootScope.$apply()
$rootScope.$digest()
$digest is already in progress
我该怎么做才能确保$scope.project阵列中的商品在我的商店中得到更新ProjectCtrl?我需要为此解决新的承诺吗?
一旦projects被加载,你使用该数组中的项目之一projects[i],让我们从理论上假设它的对象0x1在内存中。问题在于,当加载新项目(假设0x2)并更新数组时,您将更改位于数组位置(0x1)的对象,但$scope.project仍引用现在废弃的对象0x1。您不能只在数组中更改它,而必须对其进行修改,因此您无需重新绑定$scope.project变量。
projects
projects[i]
0x1
0x2
最好的解决方案是 更改 array[i] = newData 为 angular.extend(array[i], newData)。这样,您将只更改array [i]的所有属性,并且$scope.project指向内存中相同对象的指针将被更新。
array[i] = newData
angular.extend(array[i], newData)
反正,我也相信你可能要 改变 if(array[i] == object) { 到 if(array[i]._id === object._id) {和你 平等的比较(==)_以 _严格相等比较(===)。这if更适合您的原因,因为新创建的对象与旧对象不同。
if(array[i] == object) {
if(array[i]._id === object._id) {
==
===
if