AngularJS从服务模型中更新作用域

AngularJS Updating Scope from Service model

本文关键字:更新 作用域 模型 服务 AngularJS      更新时间:2023-09-26

我在控制器中有这个

$scope.activities = Activities.getAll();
$httpService.getActivities().then(function (response) {
    var activities = response.data.body;
    Activities.addMany(activities);
});

现在我的服务看起来像这样:

var _activities = [];
function addMany(activities) {
    if (activities instanceof Array) {
        _activities = _activities.concat(activities);
    }
}

:

function getAll() {
    return _activities;
}

视图在getActivities解析后不更新。我检查了一下,响应确实包含了新的活动,它们被添加到服务的_activities数组中。

问题可能是什么?我如何确保作用域总是根据服务值而变化?

根据docs (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) Javascript Array.concat方法创建一个新的数组。

这意味着getAll函数返回的_activities数组和addMany调用后产生的_activities数组不是同一个数组。

你需要做的是添加元素到现有的数组,而不是创建一个新的。而不是:

_activities = _activities.concat(activities);

你应该这样做

for (var i=0; i < activities.length; i++) {
    _activities.push(activities[i]);
}

看起来你的问题是如何从你的服务中引用你的_activities变量。当你打电话时:

$scope.activities = Activities.getAll();

您正在将初始空白数组附加到作用域。调用addMany()函数后,服务内部的数组被替换为,而不是更新。所以你的控制器仍然指向原来的空数组。

为了解决这个问题,将对象包装在一个可以设置作用域的容器中。例如:

var data = {
    activities: []
};
function addMany(activities) {
    if (activities instanceof Array) {
        data._activities = _activities.concat(activities);
    }
}
function getData() { return data; }

然后在你的控制器中这样做:

$scope.activitySrv = Activities.getData();

要引用视图中的活动,您需要使用activitySrv.activities


选择这种方法而不是简单地将其压入数组(而不是替换)的原因是,这种方法允许您使您的服务随着时间的推移而扩展。您只需要在服务中使用一个函数来检索用于作用域使用的数据,并且可以在需要时简单地添加到父对象中。

你的视图应该耦合到相关控制器的作用域变量。所以你应该在你的视图中使用$scope.activities。当有新数据进来时,应该更新这个有作用域的变量。在控制器中尝试这样做:

$httpService.getActivities().then(function (response) {
    $scope.activities = response.data.body;
    Activities.addMany($scope.activities);
});