使用angularjs 1.2.21
当我不使用带有$ http的缓存时,GET和异步响应之间显然存在摘要周期,因为在更改为插值变量后,我的页面中的可视元素已正确更新在视图中。 但是当我将缓存设置为true并且数据来自缓存时,我的视图停止更新,这意味着没有发生摘要。
angularjs doc声明即使数据来自缓存,响应也是异步的。但它没有提及消化周期。
请注意,即使响应是从缓存提供的,数据的传递也是异步的,就像实际请求一样。
要解决这个问题,我需要将$ http调用放在$ timeout(func,0)中。
那么,在您看来,这是一个错误还是它的设计?
更新:@ PSL I forked your plunk向您展示如何重现它。运行。您将看到"正在加载"第一次按下按钮时出现消息,然后它就不再出现了。删除缓存,它将每次出现。基本上我只是在Get Call中尝试改变视图,并在它完成时恢复它。
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.21/angular.js" data-semver="1.2.22"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p ng-show="load">Load in progress</p>
<p>{{i}}</p>
<button ng-click="refresh()">Refresh</button>
</body>
</html>
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $http) {
$scope.name = 'World';
$scope.i=0;
$scope.load = false;
$scope.refresh = function(){
$scope.load = true;
$http.get('test.json', {cache:true}).success(function(resp){
$scope.i++;
$scope.name = resp;
$scope.load = false;
});
}
});
更新2 :我不认为我可以在这里重现它,因为我的实际代码更复杂。实际上,修改load变量是由另一个指令(绑定到它)捕获的,它将重置第三方jquery模块。当使用缓存时,jquery模块并不总是正确地重置,这往往表明获得响应的速度太快,以至于绑定没有到达监视它的模块......
答案 0 :(得分:1)
查看下面github上的角度done()
函数,我认为这是一个错误。
(编辑 @PSL认为这不是一个错误)。
然而,仍然如此,假设此方法中没有出现错误,则无法避免使用scope.apply() - 除$apply.$$phase
之外的其他错误。
也许最好的办法是使用useApplyAsync
标志来确保它有效。
此处完成功能:
function done(status, response, headersString, statusText) {
if (cache) {
if (isSuccess(status)) {
cache.put(url, [status, response, parseHeaders(headersString), statusText]);
} else {
// remove promise from the cache
cache.remove(url);
}
}
function resolveHttpPromise() {
resolvePromise(response, status, headersString, statusText);
}
if (useApplyAsync) {
$rootScope.$applyAsync(resolveHttpPromise);
} else {
resolveHttpPromise();
if (!$rootScope.$$phase) $rootScope.$apply();
}
}
实际上,在git 1.2.x分支上,useApplyAsync
不可用。你能升级到最新版本吗?
旧的功能:
function done(status, response, headersString, statusText) {
if (cache) {
if (isSuccess(status)) {
cache.put(url, [status, response, parseHeaders(headersString), statusText]);
} else {
// remove promise from the cache
cache.remove(url);
}
}
resolvePromise(response, status, headersString, statusText);
if (!$rootScope.$$phase) $rootScope.$apply();
}