等到图像加载到 angularjs 工厂中
Posted
技术标签:
【中文标题】等到图像加载到 angularjs 工厂中【英文标题】:Wait till images are loaded inside angularjs factory 【发布时间】: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
调用。
但我找不到创建类似内容的方法。有什么建议吗?
【问题讨论】:
【参考方案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')
以上是关于等到图像加载到 angularjs 工厂中的主要内容,如果未能解决你的问题,请参考以下文章