AngularJS承诺:将承诺放入工厂,使其可在全球范围内访问和编辑



我正试图从外部JSON文件中提取数据,并将其显示给用户查看。通过各种操作,用户可以更改JSON文件返回的数据,而无需将这些更改写入文件(在本例中,通过单击div将值增加一)。我创建了一个promise服务,它成功地提取并显示数据。我甚至可以获得它,这样数据就可以在各个控制器中更改。

这就是我陷入困境的地方:我找不到对PromiseService中的数据进行任何更改的方法,因此更改无法全局传播。我如何确保控制器级别的promise数据的任何更改都会反映在PromiseService中,从而反映在应用程序中的任何数据绑定中?我对承诺很陌生,所以我对完全不同的方法持开放态度。

Plunker

HTML:

<body ng-app="pageApp" ng-controller="pageCtrl" nd-model="items">
{{items}}
<div class="button" ng-controller="buttonCtrl" ng-click="incrementValues()">
Click to increment:
<br>{{items}}
</div>
</body>

承诺服务:

pageApp.factory('PromiseService', function($http) { 
var getPromise = function() {
return $http.get('items.json').then(function(response) {
return response.data;
});
};
return {
getPromise: getPromise
};
});

按钮控制器(Plunker中的页面控制器):

pageApp.controller('buttonCtrl', function($scope, PromiseService) {
$scope.incrementValues = function()
{
PromiseService.getPromise().then(function(data) {
$scope.items = data;
for(var i = 0; i < data.items.length; i++)
{
data.items[i]['value']++;
}
}).catch(function() {
});
};
});

incrementValues函数第一次成功工作,但每次连续单击都会重新提取promise并重置数据。总之:如何在PromiseService中反映增量值,而不是局部变量?

您可以在工厂中添加一个private属性来存储项目。然后创建3种不同的方法来更新和访问该属性。

pageApp.factory('PromiseService', function($http) { 
var items = {}; // [] in case it is an array
var updateData = function(updatedData){
items = updatedData;
}
var getUpdateData = function(){
return items;
}
var getPromise = function() {
return $http.get('items.json').then(function(response) {
items = response.data;
return response.data;
});
};
return {
getPromise: getPromise,
updateData : updateData,
getUpdateData : getUpdateData 
};
});

pageApp.controller('buttonCtrl', function($scope, PromiseService) {
$scope.items = [];
//You should call this method to retrieve the data from the json file
$scope.getData = function(){
PromiseService.getPromise().then(function(data) {
$scope.items = data;            
}).catch(function() {
});
}
$scope.incrementValues = function(){
for(var i = 0; i < $scope.items.length; i++){
$scope.items[i]['value']++;
}     
PromiseService.updateData($scope.items); //This could be skipped in case you do not want to 'store' these changes. 
};
});

然后在其他控制器中,您可以使用相同的服务来检索updated Data,如下所示:

$scope.items = PromiService.PromiseService();

将来,您还可以创建一个新方法来更新json本身,而不是存储在内部的

函数每次被调用时都会创建一个新的$http调用,因此每次被调用都会返回一个新承诺,封装新数据。

您每次都需要返回相同的承诺:

var thePromise = $http.get('items.json').then(function(response) {
return response.data;
});
var getPromise = function() {
return thePromise;
};