因此,我正在学习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。在我的模板中,当loading变量设置为false时,我使用ng-show来显示图像。
如果我在imagesLoaded回调之外(例如ajax请求完成时)将load设置为false,那么一切都会按预期进行,当我在imagesLoaded函数内部设置它时,模板不会使用新的load值进行更新。注意console.log('已加载图像');确实在图像加载后打印到控制台,所以我知道imagesLoaded插件可以正常工作。
最佳答案
由于一旦加载图像后便会异步调用imagesLoaded
回调,因此Angular不知道that.isLoading()
方法调用的值已更改。 Angular使用脏检查是为了为您提供易于使用的2种方式的数据绑定。
如果您有这样的模板:<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,因为您的模型更改仅是本地的。