AngularJS – 如何强制范围更新(对数组项的承诺)

前端之家收集整理的这篇文章主要介绍了AngularJS – 如何强制范围更新(对数组项的承诺)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Angular中创建了一个看起来像这样的控制器(为简洁而编辑):
function AppCtrl($scope,$http,$location,$dataService) {
    $scope.projects = $dataService.data.projects;
}

这从我的$dataService服务正确加载$scope.projects承诺.

app.service('$dataService',function($q,$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,config) {
            updateObjectInArray(dataService.data.projects.$$v,project,data);
        }).error(function(data,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()请求成功),AppCtrl中的$scope.projects正确更新(项目数组),但ProjectCtrl中的$scope.project是没有更新.我可以在updateObjectInArray()函数中记录array [i],它会完全记录我的期望,我可以在AppCtrl中记录$scope.projects,它会相应更新,但是当我尝试在我的日志中记录$scope.project ProjectCtrl控制器,它没有相应更新.

我认为原因是因为我在更新updateObjectInArray()中的array [i]对象后不得不调用$rootScope.$apply()或$rootScope.$digest(),但是,我得到的错误是$digest已经是进行中.

我需要做些什么才能确保我的$scope.project项在我的ProjectCtrl中更新?我是否需要为此解决新的承诺?

加载项目后,你正在使用数组项目[i]中的一个项目,理论上我们假设它是内存中的对象0x1.问题是当加载一个新项目时(让我们假设为0x2),并且你更新了数组,你正在改变位于数组位置的对象(0x1),但是$scope.project仍然引用了现在放弃的对象为0x1.您不能只在数组中更改它,您必须修改它,因此您不需要重新绑定$scope.project变量.

最好的解决方案是将array [i] = newData更改为angular.extend(array [i],newData).这样,你只需更改array [i]的所有属性,并且当$scope.project指向内存中的同一对象时,它将被更新.

无论如何,我也相信你可能想要改变if(array [i] == object){to if(array [i] ._ id === object._id){和你的等式比较(==)到严格的相等比较(===).这样可以更好地适合您的原因,因为新创建的对象与旧对象不同.

猜你在找的Angularjs相关文章