Javascript imagesLoaded插件不适用于Angular JS

Javascript imagesLoaded插件不适用于Angular JS,javascript,jquery,ajax,angularjs,image,Javascript,Jquery,Ajax,Angularjs,Image,所以我正在学习AngularJS,我正在构建一个小的web应用程序,允许你随机点击图片。基本上,单击“下一步”按钮,将下载并显示一个图像,当单击“上一步”按钮时,它将转到堆栈中的上一个图像 我想显示一个加载微调器并禁用后退/前进按钮,直到对新图像的ajax请求完成,并且图像完全加载 我的图像控制器的结构如下: app.controller('ImageController', ['imageService', function(imageService) { var that = thi

所以我正在学习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();
}]);
如果您注意到该.fetchSkin()函数的内部,我将调用imagesLoaded插件,然后在加载图像时,我将该.loading设置为false。在我的模板中,当加载变量设置为false时,我使用ng show来显示图像


如果在imagesLoaded回调之外将loading设置为false(如ajax请求完成时),则一切正常,当我在imagesLoaded函数内部将其设置时,模板不会使用新的loading值更新。注意console.log('imagesloaded');加载图像后会打印到控制台,因此我知道imagesLoaded插件工作正常。

由于加载图像后会异步调用
imagesLoaded
回调,Angular不知道
that.isLoading()
方法调用的值已更改。这是因为Angular使用脏检查为您提供易于使用的双向数据绑定

如果您有这样的模板:

更改值后,它不会更新

您需要手动告诉angular有关数据更改的信息,这可以通过手动调用$digest来完成

$scope.$digest();
就在你这么做之后

 console.log('images loaded');
 that.setLoading(false);
可以工作的伪代码(从我的指令复制和粘贴):


只要您只在异步回调中更改控制器$scope,就不需要调用
$apply()
在$rootScope上运行$digest,因为您的模型更改只是本地的。

这可能会有助于实现这一点。加载本地,否则使用getter和setter是没有用的。我感谢您的解释,我想这是关于angular的,我只是没有完全理解。不用担心,尽管我花了一段时间才完全理解angular是如何工作的。同样,对$digest和脏检查FTW的堆栈溢出解释!另一方面,如果您获取Angular的源代码并转到
ngClick
指令实现,您将看到它们执行$scope.$apply(),因为浏览器事件(onClick、onMouseLeave等)也是异步的:)我搜索了半个小时为什么我的ng if不工作,原因也是一样的,更新值后需要运行$scope.digest()。
//inside your controller
$scope.isLoading = false;

// just another way of using imagesLoaded. Yours is ok.
$element.imagesLoaded(function() {
    $scope.isLoading = true;
    $scope.$digest();
});