所以我正在学习AngularJS,我正在构建一个小型的Web应用程序,允许您随机点击图像。基本上,您单击下一个按钮并下载并显示图像,当您单击后退按钮时,它将转到堆栈中的上一个图像。
我想显示一个加载微调器并禁用后退/前进按钮,直到新图像的ajax请求完成,并且图像已完全加载
我的图像控制器的结构如下:
app.controller('ImageController', ['imageService', function(imageService) {
var that = this;
that.position = 0;
that.images = [];
that.loading = false;
that.isLoading = function() {
return that.loading;
}
that.setLoading = function(isLoading) {
that.loading = isLoading;
}
that.currentImage = function() {
if (that.images.length > 0) {
return that.images[that.position];
} else {
return {};
}
};
that.fetchSkin = function() {
that.setLoading(true);
imageService.fetchRandomSkin().success(function(data) {
// data is just a js object that contains, among other things, the URL for the image I want to display.
that.images.push(data);
that.imagesLoaded = imagesLoaded('.skin-preview-wrapper', function() {
console.log('images loaded');
that.setLoading(false);
});
});
};
that.nextImage = function() {
that.position++;
if (that.position === that.images.length) {
that.fetchSkin();
}
};
that.previousImage = function() {
if (that.position > 0) {
that.position--;
}
};
that.fetchSkin();
}]);
如果您注意到that.fetchSkin()函数内部,我正在调用imagesLoaded插件,然后在加载图像时我将that.loading设置为false。在我的模板中,我使用ng-show在加载变量设置为false时显示图像。
如果我在imagesLoaded回调之外设置加载为false(就像ajax请求完成时那样),那么一切都按预期工作,当我在imagesLoaded函数中设置它时,模板不会使用新的加载值更新。注意console.log('images loaded');一旦图像加载就会打印到控制台,所以我知道imagesLoaded插件工作正常。
答案 0 :(得分:2)
由于在加载图像后异步调用imagesLoaded
回调,Angular不知道that.isLoading()
方法调用的值发生了变化。这是因为Angular使用脏检查为您提供易于使用的双向数据绑定。
如果你有这样的模板:
<div ng-show="isLoading()"></div>
更改值后不会更新。
您需要手动告知有关数据更改的角度,并且可以通过手动调用$ digest来完成。
$scope.$digest();
在你做完之后
console.log('images loaded');
that.setLoading(false);
可以工作的伪代码(从我的指令中复制和粘贴):
//inside your controller
$scope.isLoading = false;
// just another way of using imagesLoaded. Yours is ok.
$element.imagesLoaded(function() {
$scope.isLoading = true;
$scope.$digest();
});
只要您在异步回调中仅更改控制器$ scope,就无需调用$apply()
在$ rootScope上运行$ digest,因为您的模型更改只是本地的。