因此,我正在学习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,因为您的模型更改仅是本地的。

09-28 08:29