Подтвердить что ты не робот

Как вызвать функцию JQuery из AngularJS при изменении вида

Я новичок в AngularJS, и я имею дело с проблемой при внедрении jQuery custom scrolller в мое приложение.

Мне нужен скроллер для обновления, когда я обновляю содержимое с помощью Angular, для этого скроллер имеет метод update. Моя проблема в том, что я не знаю, где ее называть. Разметка для содержимого следующая:

<div class="scroll-list nice-scrollbars">
    <ul class="gallery clearfix">
        <li class="extra-alt" ng-repeat="item in relatedItems.data">
            ...
        </li>
    </ul>
</div>

Я пытался вызвать метод обновления в ветке успеха Angular $http.post:

$scope.relatedItems = $http.post($scope.url, {
    'filterType': 'related', 'film': id
}).success(function() {
    $(".nice-scrollbars").mCustomScrollbar('update');
});

Это не сработало, я думаю, потому что, когда вызывается метод success, содержимое представления еще не обновляется (я мог видеть его с помощью функции alert, данные появились после закрытия диалогового окна)

Единственным способом, с помощью которого я мог работать в полосах прокрутки, было использование расширенного свойства scroller для просмотра изменений в содержимом (это параметры, переданные на полосу прокрутки):

var scrollbarOpts = {
    scrollButtons:{
        enable:true
    },
    advanced:{
        updateOnContentResize: true
        //@TODO: get rid of this, correctly find where to call update method
    }
}

Это плохая практика, так как эти параметры уменьшают производительность всего script. Я хотел бы знать, где это подходящее место для вызова методов jQuery, необходимых для обновления DOM по мере необходимости, или как такая привязка для корректного просмотра изменений в AngularJS?

4b9b3361

Ответ 1

Обработка DOM должна выполняться в директиве (а не в контроллере). В директиве должна быть $watch() ваша модель для изменений, а обратный вызов часов должен выполнять манипуляции с JQuery DOM. Иногда $evalAsync требуется для запуска кода jQuery после того, как Angular обновил/модифицировал DOM (но до отображения браузера. Используйте $timeout, если вы хотите выполнить некоторые действия после отображения браузера). См. этот ответ, где я представил скрипту, показывающую, как использовать директиву для $watch() свойства модели, и я использовал $evalAsync в функции mock fetch().

В вашем конкретном случае я предлагаю вам сначала попробовать следующее: в директиве:

scope.$watch("relatedItems.data", function() {
   $(".nice-scrollbars").mCustomScrollbar('update');
});

и если это не сработает, попробуйте следующее:

scope.$watch("relatedItems.data", function() {
   scope.$evalAsync(  // you might need to wrap the next line in a function, not sure
      $(".nice-scrollbars").mCustomScrollbar('update')
   );
});