1

Я создал небольшую функцию, позволяющую пользователям искать названия фильмов. Это запросы JSON от tmdb.org, которые возвращают такие вещи, как заголовки, даты и плакаты URL.Дождитесь загрузки изображений внутри фабрики angularjs

Контроллер:

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 в браузере, которая занимает некоторое время.

Это вызывает 2 вещи. Прежде всего, чтобы вырезать счетчик, прежде чем изображения будут отображаться в браузере, и поскольку все изображения загружены как асинхронные, это вызывает эффект водопада.

Самый простой способ решить эту проблему - отложить вызов .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> 
+0

Спасибо за предложение. Я не очень хорошо работал, но ваше предложение использовать обещания привело к ответу. Найденный plunkr где-то, что я сделал то, что хотел. Поэтому я адаптировал его> http://plnkr.co/edit/assAAiz0NnV1bt7ASY9z?p=preview и делает то, что хочу :). –

+0

cool .. в моем коде выше Я жду, когда DOM будет обновлен, чтобы установить изображение обещает ... :) – kukkuz

+0

Я не получил эту часть, хотя 'var imageList = $ ('# my_tenants img') ; 'вы используете селектор jquery для заполнения массива imageList? –

Смежные вопросы