У меня есть компонент пользовательского интерфейса, который имеет обратную связь $watch
по своей ширине (причина не имеет отношения к этому сообщению). Проблемы заключается в том, что в некоторых случаях:
- Ширина изменяется от не углового контекста ->
- Там нет
$digest
цикла -> - Моего
$watch
обратного вызова не вызывается.
Хотя мое приложение является полным угловым приложением, все еще есть случаи, когда код выполняется в неконкурентном контексте. Например: JQuery calles window.setTimeout
- так что даже если мой код под названием JQuery
из углового контекста, вызов обратного вызова timeout вызывается в неконкурентном контексте, и мой обратный вызов $watch
не будет выполнен после этого.
Кстати, даже угловой сами называют window.setTimeout
в их AnimatorService
...
Так что мой вопрос: Как я могу убедиться, что $digest
цикла всегда выполняется после того, как любой код выполняется? (Даже если код является третьим участником код ...)
Я думал о переопределении оригинальный метод window.setTimeout
но:
- Он чувствует себя немного некрасиво и опасно.
- Я боюсь, что он не будет охватывать все варианты использования.
Добавление plunker. Образец plunker содержит:
- Элемент, который может быть скрыт с помощью JQuery
fadeOut
метод. - Кнопка, которая выполняет вызов
fadeOut
для сокрытия элемента. - Текст, отображающий статус отображения элемента (
Shown!!!
илиHidden!!!
). Этот текст обновляется$watch
ing на элементеdisplay
Недвижимость. - Кнопка, которая ничего не делает, кроме как инициировать некоторый угловой код, чтобы вызвать цикл
$digest
.
Flow:
- Нажмите кнопку
Fade Out
-> элемент будет скрыт, но текст статуса останетсяShown!!!
. Вы можете ждать вечность сейчас - или: - Нажмите кнопку
Do Nothing
-> текст будет меняться.
Почему?
При нажатии на кнопку Fade Out
JQuery.fadeOut
вызывается метод window.setTimeout
. После этого вызывается мой обратный вызов $watch
, но элемент все еще не скрыт. Элемент скрыт только после вызова обратного вызова таймаута, но тогда нет цикла $digest
(и у меня нет способа, которым я знаю, чтобы вызвать его). Только в следующий раз, когда будет запущен угловой код, функция $watch
будет вызвана снова, и статус будет обновлен.
Почему [$ scope. $ Apply()] (http://docs.angularjs.org/api/ng.$rootScope.Scope#$apply) не решение? – Stewie
Не совсем - проблема в том, что я не могу получить какое-либо событие, когда этот код работает. Как и в примере, если какая-то сторонняя сторона (например, JQuery или Angular) вызывает 'window.setTimeout', мой код не будет выполняться, когда вызывается обратный вызов таймаута, поэтому я не могу добавить вызов' $ scope.apply'. –
Боюсь, вам придется настроить демонстрацию плункера, потому что ваше дело звучит довольно необычно. – Stewie