imagesLoaded插件不能与Angular JS一起使用

时间:2014-11-11 18:07:55

标签: javascript jquery ajax angularjs image

所以我正在学习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插件工作正常。

1 个答案:

答案 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,因为您的模型更改只是本地的。