防止AngularJS使用缓存数据返回承诺
我使用服务在控制器之间共享数据。但是,即使在发出新请求时,该服务也会返回缓存数据的承诺。根据防止AngularJS使用缓存数据返回承诺,angularjs,promise,Angularjs,Promise,我使用服务在控制器之间共享数据。但是,即使在发出新请求时,该服务也会返回缓存数据的承诺。根据defer实例的创建位置,返回实时数据但双向绑定中断,或者双向绑定工作但返回缓存数据 如何防止使用缓存数据返回承诺,并保持双向绑定 我提出了一个plunker来说明这一情况:为了完整起见,这里是麻烦制造服务: app.service('myService', function($http, $q) { // When instancing deferred here two way bindin
defer
实例的创建位置,返回实时数据但双向绑定中断,或者双向绑定工作但返回缓存数据
如何防止使用缓存数据返回承诺,并保持双向绑定
我提出了一个plunker来说明这一情况:为了完整起见,这里是麻烦制造服务:
app.service('myService', function($http, $q) {
// When instancing deferred here two way binding works but cached data is returned
var deferred = $q.defer();
this.get = function(userId) {
// When instancing deferred here two way binding breaks but live data is returned
//var deferred = $q.defer();
console.log('Fetch data again using id ', userId);
var url = userId + '.json';
$http.get(url, {timeout: 30000, cache: false})
.success(function(data, status, headers, config) {
deferred.resolve(data, status, headers, config);
})
.error(function(data, status, headers, config) {
deferred.reject(data, status, headers, config);
});
return deferred.promise;
};
});
更新:问题不是数据被缓存了,而是我不知道如何共享数据,共享数据不能是原语。请参见下面我自己的答案。因为$http返回一个延迟对象,所以您在这里所做的实际上是过火了。当我将您的服务改为以下服务时,它似乎工作得很好 编辑 要更新控制器
SecondCtrl
,在保持代码结构不变的情况下,最简单的方法是使用$rootScope.$broadcast
在FirstCtrl
中定义的事件中广播新数据,并使用$scope.$on
在其他控制器中捕获广播的事件。我已经更新了Plunker,现在您的数据已同步
在FirstCtrl
中修改了loadUserFromMyService
函数:
$scope.loadUserFromMyService = function(userId) {
var promise = myService.get(userId);
promise.then(
function(data) {
console.log('UserData', data);
$scope.data = data;
$rootScope.$broadcast('newData', data);
},
function(reason) { console.log('Error: ' + reason); }
);
};
$scope.$on('newData', function (evt, args) {
console.log('dataChanged', args);
$scope.data = args;
});
添加到SecondCtrl
:
$scope.loadUserFromMyService = function(userId) {
var promise = myService.get(userId);
promise.then(
function(data) {
console.log('UserData', data);
$scope.data = data;
$rootScope.$broadcast('newData', data);
},
function(reason) { console.log('Error: ' + reason); }
);
};
$scope.$on('newData', function (evt, args) {
console.log('dataChanged', args);
$scope.data = args;
});
在Luke Kende的帮助下,我想出了一个简单的共享数据的解决方案。这里有一个提示:。请参阅下面的代码 重要的一点是,共享对象不是原语。当我尝试不同的解决方案时,我首先声明了共享对象并将其赋值为
null
,这是一个禁忌。使用空对象可以使它工作
var app = angular.module('plunker', []);
// Service
app.service('myService', function($http, $q) {
//object that will be shared between controllers
var serviceData = {
items: []
};
return {
data: serviceData, //pass through reference to object - do not use primitives else data won't update
get: function(url, overwrite) {
if (serviceData.items.length === 0 || overwrite){
$http.get(url, {timeout: 30000})
.success(function(data, status, headers, config) {
//could extend instead of ovewritting
serviceData.items = data;
})
.error(function(data, status, headers, config) {
serviceData.items = {status: status};
});
}
return serviceData;
},
empty: function(){
serviceData.items = [];
},
more: function(){
//do some other operations on the data
}
};
});
// Controller 1
app.controller('FirstCtrl', function( myService,$scope) {
//myService.data is not initialized from server yet
//this way don't have to always use .then() statements
$scope.data = myService.data;
$scope.getTest = function(id){
myService.get('test' + id + '.json',true);
};
$scope.addItem = function() {
$scope.data.items.push({'title': 'Test ' + $scope.data.items.length});
};
$scope.delItem = function() {
$scope.data.items.splice(0,1);
};
});
// Controller 2
app.controller('SecondCtrl', function( myService,$scope) {
//just attach myService.data and go
//calling myService.get() results in same thing
$scope.data = myService.data;
//update the the data from second url -
$scope.getTest = function(id){
myService.get('test' + id + '.json',true);
};
$scope.empty = function(){
myService.empty();
};
});
嗯,就为了这项运动-如果你做了
var url=userId+”.json?cacheBreaker=“+Date.now()”,这会发生吗代码>?是的,我之前试过那条路,但没有用。当请求不同的json文件时,返回的响应包含预期的用户数据。嗨,罗伊!不幸的是,这两个绑定当时不起作用。还是我遗漏了一些明显的东西?我想你可能误解了数据绑定的工作原理。给我几分钟时间更新我的答案,以便更详细地解释。嘿@JohnP,对不起,花了这么长时间。我已经更新了我的答案。现在您的数据已同步。感谢您的努力。在寻找答案的过程中,我发现一个网站描述了控制器之间共享数据的一些方法,第三种方法似乎是可行的。事实上,这和你提出的解决方案是一样的——使用广播和电视。我提出了另一个解决方案,如下所示,这样就不必使用$broadcast和$on。感觉有点干净。