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

AngularJs: Запуск директив после полного просмотра представления

Я новичок во всех Angular World, и я столкнулся с проблемой управления директивами.

Я работаю над проектом, который использует вкладки, и я хочу расширить его функциональность, чтобы обрабатывать переполненные вкладки, когда размер окна уже, чем ширина всех моих вкладок, поэтому мне нужно рассчитать некоторые размеры элементов для достижения этого, Вкладки построены из объекта в области $scope, проблема в том, что директива, которая вычисляет размеры, запускается до полного компиляции представления.

Plnkr Ссылка: http://plnkr.co/edit/LOT4sZsNxnfmQ8zHymvw?p=preview

Что я пробовал:

  • загрузка шаблона в директиву с помощью templateUrl
  • работа с transclude
  • использовать $last в ng-repeat
  • попытайтесь изменить порядок директивы и создайте фиктивную директиву на каждой вкладке, чтобы вызвать событие

Я думаю, что есть какое-то событие AngularJs или свойство для обработки этой ситуации.

Пожалуйста, помогите:)

4b9b3361

Ответ 1

Я делаю ветку на вашем плунжере, я думаю, это то, что вы искали

Я изменяю вашу директиву на

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

Затем на вашем HTML я добавил директиву

 <li ng-repeat="tab in tabs" on-finish-render-filters>

И последнее, что я поставил код, который я хочу запустить после повторного завершения

$scope.$on('ngRepeatFinished', function (ngRepeatFinished) {
        $scope.tabs = [{
            index: 1,
            title: "Tab 1",
            link: "/tab1/"
        },{
            index: 2,
            title: "Tab 2",
            link: "/tab2/"
        },{
            index: 3,
            title: "Tab 3",
            link: "/tab3/"
        },{
            index: 4,
            title: "Tab 4",
            link: "/tab4/"
        }];

  });

http://plnkr.co/edit/TGduPB8FV47QvjjLnFg2?p=preview

Ответ 2

У AngularJS, похоже, нет надежных обратных вызовов после рендеринга для директив, используемых в ng-repeat. [1]

Возможно, вы можете решить эту проблему на уровне CSS, добавив "чувствительный" элемент управления переполнением для конкретных экранов.

Обновление: теперь есть способ сделать это с помощью вложенных $тайм-аутов. См.: http://lorenzmerdian.blogspot.de/2013/03/how-to-handle-dom-updates-in-angularjs.html

Ответ 3

Вы можете добавить часы на фактические элементы DOM, чтобы узнать, когда ваш ng-repeat загружен в DOM.

Дайте вашей ul id, скажем #tabs

$scope.$watch(
    function () { return document.getElementById('tabs').innerHTML },  
    function(newval, oldval){
        //console.log(newval, oldval);
        //do what you like
    }, true);

Ответ 4

Согласно вашим комментариям, у вас уже есть решение, которое работает... и его единственное решение, о котором я знаю: $timeout.

Вопрос в том, чего вы хотите достичь? Вы хотите обратный вызов, когда выполняется весь рендеринг. Хорошо, хорошо, но как angular знает об этом? В современном приложении, которое вы, по-видимому, разрабатываете при использовании angular, ревердер может произойти все время! Событие js может происходить, когда данные загружаются из бэкэнд, даже сразу после инициализации приложения, что приводит к повторной передаче. Движение мыши пользователем может инициировать реиндексирование элементов, которые даже за пределами угловой области из-за правил CSS. В любое время может произойти перезарядка.

Итак, с этими соображениями, о чем может говорить angularJS, когда делается рендеринг? Он может только сказать вам, когда текущая $apply и/или $digest цепочка обрабатывается, иначе очередь событий браузера пуста. Именно это единственная информация, о которой знает угловой. И вы используете $timeout с задержкой 0 для этого.

Да, вы правы, в более широком применении, которое может быть сложным до такой степени, что оно не является надежным. Но в этом случае вы должны подумать о том, как вы можете решить это по-другому. F.I. если повторение происходит позже, должна быть причина, как новые данные, которые загружаются из бэкэнд. Если это так, вы знаете, когда данные загружены и, следовательно, происходит переиздание, и поэтому вы точно знаете, когда вам нужно обновлять свои ширины.