【问题标题】:Wait till images are loaded inside angularjs factory等到图像加载到 angularjs 工厂中
【发布时间】:2016-11-21 02:14:50
【问题描述】:

我创建了一个小功能,允许用户搜索电影标题。这会执行来自 tmdb.org 的 JSON 请求,该请求会返回标题、日期和 url 的海报等内容。

控制器:

    angular.module('movieSeat')
        .factory('moviesearchFactory', ['$http', '$q', '$rootScope', function ($http, $q, $rootScope) {

            var factory = {};

            function httpPromise(url) {
                var deferred = $q.defer();
                $http({
                    method: 'JSONP',
                    url: url
                })
                    .success(function (data) {
                        deferred.resolve(data.results);
                    })
                    .error(function () {
                        deferred.reject();
                    });
                return deferred.promise;
            }

            factory.getMovies = function (searchquery) {
                return httpPromise('http://api.themoviedb.org/3/' + 'search/movie?api_key=a8f7039633f2065942cd8a28d7cadad4' + '&query=' + encodeURIComponent(searchquery) + '&callback=JSON_CALLBACK')
            }

            return factory;

        }]);

工厂:

    angular.module('movieSeat')
        .controller('moviesearchCtrl', ['$scope', 'moviesearchFactory', function ($scope, moviesearchFactory) {

            $scope.createList = function (searchquery) {
                $scope.loading = true;
                moviesearchFactory.getMovies(searchquery)
                    .then(function (response) {
                        $scope.movies = response;
                    })
                    .finally(function () {
                        $scope.loading = false;
                    });

            }

        }]);

模板:

    <div ng-controller="moviesearchCtrl" id="movieSearch">

        <div class="spinner" ng-show="loading">Loading</div>
        <input ng-model="searchquery" ng-change="createList(searchquery)" ng-model-options="{ debounce: 500 }" />
        {{ search }}

        <ul>
            <li ng-if="movie.poster_path" ng-repeat="movie in movies | orderBy:'-release_date'">
                <span class="title">{{ movie.title }}</span>
                <span class="release_date">{{ movie.release_date }}</span>
                <img ng-src="https://image.tmdb.org/t/p/w300_and_h450_bestv2/{{ movie.poster_path }}" class="poster"/>
            </li>
        </ul>
    </div>

这个特性的问题是微调器类只等待请求的数据。但是只是加载一些JSON并不需要很长时间,它是从浏览器中的api下载图像需要一段时间。

这会导致两件事。在图像在浏览器中呈现之前先移除微调器,并且由于图像都是异步加载的,因此会导致瀑布效果。

解决此问题的最简单方法是延迟控制器中的.then 调用,直到为用户下载图像,然后进入.finally 调用。

但我找不到创建类似内容的方法。有什么建议吗?

【问题讨论】:

    标签: javascript angularjs image angularjs-ng-repeat angular-directive


    【解决方案1】:

    试试这个并告诉我:

    想法是使用指令来发出渲染完成事件:

    dashboard.directive('onFinishRender', function ($timeout) {
        return {
            restrict: 'A',
            link: function (scope, element, attr) {
                if (scope.$last === true) {
                    $timeout(function () {
                        scope.$emit(attr.onFinishRender);
                    });
                }
            }
        }
    });
    

    在控制器中保留等待图像加载承诺的事件监听器:

        $scope.$on('dataLoaded', function(ngRepeatFinishedEvent) {
            // your code to check whether images has loaded
            var promises = [];
            var imageList = $('#my_tenants img');
            for(var i = 0; i < imageList.length; i++) {
                promises.push(imageList[i].on('load', function() {}););
            }
            $q.all(promises).then(function(){
                // all images finished loading now
                $scope.loading = false;
            });
        });
    

    在html端:

    <div id = "my_tenants">
        <div ng-repeat="tenant in tenants" on-finish-render="dataLoaded">
            // more divs
        </div>
    </div>
    

    【讨论】:

    • 感谢您的建议。我没有得到很好的工作,但你使用承诺的建议导致了答案。在某个地方找到了一个可以满足我要求的 plunkr。所以我对其进行了调整 > plnkr.co/edit/assAAiz0NnV1bt7ASY9z?p=preview 并做我想做的事情:)。
    • cool.. 在我上面的代码中,我正在等待更新 DOM 以设置图像承诺... :)
    • 虽然var imageList = $('#my_tenants img'); 没有得到这部分内容,但您是否使用 jquery 选择器来填充 imageList 数组?
    • 选择加载数据的 ng-repeat 中的所有图像...在您的代码中它看起来像 $('#movieSearch img')
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多