AngularJS: Огоньте событие сразу после $scope. $Digest

В моем приложении AngularJS есть несколько моментов, по которым я хочу подождать, чтобы область $обрабатывалась в DOM, а затем запустил на ней некоторый код, например jQuery fadeIn.

Есть ли способ прослушать какое-нибудь сообщение digestComplete?

Мой текущий метод - сразу после установки любых переменных $scope, которые я хочу отображать, используйте setTimeout с задержкой в ​​0 мс, чтобы он позволил области завершить переваривание, а затем запустить код, который отлично работает. Проблема только в том, что я очень редко вижу рендеринг DOM перед возвратом setTimeout. Мне нужен метод, который гарантированно срабатывает после дайджеста, и перед рендерингом. Любые идеи?

Ответы

Ответ 1

В этом jQuery fade-in-and-out fiddle (который я нашел на JSFiddles Примеры wiki page) автор определяет директиву "fadey" и выполняет jQuery fadeIn (или fadeOut) в функции директивной ссылки "

<li ng-repeat="item in items" fadey="500">
...
myApp.directive('fadey', function() {
return {
    restrict: 'A',
    link: function(scope, elm, attrs) {
        var duration = parseInt(attrs.fadey);
        if (isNaN(duration)) {
            duration = 500;
        }
        elm = jQuery(elm); // this line is not needed if jQuery is loaded before Angular
        elm.hide();
        elm.fadeIn(duration)

Другим возможным решением является использование $evalAsync: см. этот комментарий Мишко, в котором он утверждает:

AsyncEval после построения DOM, но до отображения браузера. Я считаю, что это время, когда вы хотите присоединить плагины jquery. в противном случае у вас будет мерцание. если вы действительно хотите сделать после рендеринга браузера вы можете сделать $defer (fn, 0);

($ defer было переименовано в $timeout).

Однако я считаю, что использование директивы (поскольку вы манипулируете DOM) - лучший подход.

Здесь SO post, где ОП пытался прослушивать события $viewContentLoaded в области (что является еще одной альтернативой), чтобы применить некоторые функции jQuery. Предложение/ответ было снова использовать директиву.

Ответ 2

В качестве альтернативы этот пример будет работать так же, как встроенная в AngularJS директива ng-show, за исключением того, что она будет затухать или на основе состояния AngularJS:

<li ng-repeat="item in items" ng-ds-fade="{condition}">
<!-- E.g.: ng-ds-fade="items.length > 0" -->
...
myApp.directive('ngDsFade', function () {
  return function(scope, element, attrs) {
    element.css('display', 'none');
    scope.$watch(attrs.ngDsFade, function(value) {
      if (value) {
        element.fadeIn(200);
      } else {
        element.fadeOut(100);
      }
    });
  };
});

Источник: http://www.codeproject.com/Articles/464939/Angular-JS-Using-Directives-to-Create-Custom-Attri

Ответ 3

Если все, что вы хотите, должно запускать некоторые элементы jQuery, почему бы не попробовать Angular -UI jQuery Passthrough?