AngularJS - 如何强制使用范围,以更新(数组项承诺) [英] AngularJS - how to force a scope to update (promise for array item)

查看:215
本文介绍了AngularJS - 如何强制使用范围,以更新(数组项承诺)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个角控制器,看起来像这样(编辑为简洁起见):

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 ?我需要解决一个新的承诺呢?

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 角.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆