Начал изучать этот фрэймворк, столкнулся с банальнейшей задачей которую не могу реализовать.
Необходимо считать данные из DOM после того как было изменено значение в scope и отрендерено в представление.
Если считывать значение из DOM сразу после изменения скопа, то естественно мы ничего не получаем, так как DOM еще не отрендерен.
Задача в целом звучит следующим образом:
Есть scope в котором есть свойство (длинна промежутка времени) по которому строится горизонтальный грид. Задача такова, что если длинна этого грида становится больше видимой области экрана, нужно сделать его горизонтальную прокрутку.
Грид идет не в таблице а на DIVах. колонки выстраиваются друг за дружкой справа налево и имеют float:left.
Соответственно что бы они не съезжали друг под друга при нехватке места в ширину, нужно задать родительскому контейнеру статичную ширину в которую влезут все колонки грида.
Для этого мне нужно отловить событие когда AngularJS дорисовал все колонки, считать их размер с отступами, и задать обертке сумму ширин этих колонок.
Как я только не пробовал это делать… Я наткнулся на такой топик на SO
stackoverflow.com/questions/12102366/angularjs-fire-an-event-immediately-after-scope-digest
И начал реализовывать через directives и $evalAsync. Но правильного результата добиться не могу.
Вот пример кода:
angular.module('mailingDirectives', [])
.directive('scroller', function($timeout) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
scope.$watch(attrs.scroller, function(){
var width=0;
scope.$evalAsync(function(){
element.find('>div').each(function(){
width += $(this).outerWidth(true);
})
var wrapper = element.parent();
if (wrapper.width() < width) {
wrapper.css('overflow-x', 'scroll');
} else {
wrapper.css('overflow-x', 'hidden');
}
element.width(width);
})
})
}
}
});
<div class="quotesGridWrapper span9">
<div scroller="dateSpan" class="quotesGrid">
<div class="month" ng-repeat="month in quotesGrid">
<span class="monthName">{{month.name}} {{month.year}}</span>
<div class="day" ng-repeat="day in month.days">
<div class="date">
{{day.date.getDate()}} <br /> <span title="">{{day.dowShot}}</span>
</div>
<div class="mailBtn">
<a class="btn btn-small"><i class="icon-envelope"></i></a>
</div>
<div class="quotes">
<div class="full">
60
</div>
<div class="free">
10
</div>
<div class="busy">
50
</div>
</div>
</div>
</div>
</div>
</div>
В итоге сейчас имеем то что при считывании ширины колонок в гриде оно считывает их каждый раз по разному. Т.е. добавление новых и процесс считывания чередуются между собой. Раз считает что там 5 колонок, в другой раз что 7 и т.п.
Т.е. $evalAsync в реальности не вызывается после $digest.