Отложить угловое выполнение часов после $digest (повышение DOM-события)
У меня есть часы, которые запускают событие DOM:
scope.$watch(function() { return controller.selected; }, function(selected) {
if (selected) {
$input.trigger('focus');
}
});
Проблема в том, что у меня есть обработчик "focus", который выполняет scope.$apply
.
$input.bind('focus', function() {
scope.$apply(function() { controller.focused = true; });
});
Итак, когда мой $watch
запускается изнутри $digest
, он вызывает ошибку, потому что он пытается запустить еще один $digest
.
Обходной путь, который у меня есть, - поставить триггер в $timeout
.
scope.$watch(function() { return controller.selected; }, function(selected) {
if (selected) {
$timeout(function() { $input.trigger('focus'); });
}
});
Это работает... до сих пор. Это правильный способ справиться с этим? Я не уверен, что это поймает каждый случай и хотел бы узнать, есть ли одобренный angular способ откусить часть кода после дайджеста.
Спасибо!
Ответы
Ответ 1
$timeout обычно используется для запуска чего-то после цикла дайджеста (и после браузера делает).
$timeout
приведет к выполнению другого цикла дайджеста после выполнения функции. Если ваш trigger
не влияет ни на что Angular, вы можете установить аргумент invokeApply
на false
, чтобы избежать запуска другого цикла дайджеста.
Если вы хотите, чтобы ваш обратный вызов выполнял до, браузер отображает: Если код поставлен в очередь с помощью $evalAsync
из директивы, он должен запускаться после того, как DOM был обработан с помощью Angular, но до браузер делает. Однако, если код поставлен в очередь с помощью $evalAsync
с контроллера, он будет запущен до того, как DOM будет обработан Angular (и до отображения браузера). См. Также fooobar.com/questions/18454/....
Ответ 2
Как и все говорят: "Вы не должны делать вещи DOM в своем контроллере.
Вот решение, которое применяет двустороннюю привязку данных к фокусу. Теперь ваш фокус связан с переменной. Поэтому, когда вы устанавливаете переменную в true, она фокусируется на соответствующем элементе, и когда элемент получает фокус, задается переменная.
http://plnkr.co/edit/CvPCVxy4MfJEM1UksrrA?p=preview
Теперь мы успешно отделили фокус от кода контроллера. Он также заботится обо всех проблемах с таймаутом $(я думаю). Единственное, что вам нужно знать, это то, что вы не должны использовать одну и ту же переменную для привязки к фокусу двух разных элементов.
РЕДАКТИРОВАТЬ: Обновлен плунж, поскольку предыдущий не работал нормально.