Угловой наблюдатель не работает, когда слушатель - Дата () функция

Я знаю, что задаю вопрос, у которого есть чрезвычайно простой ответ (я плохо знаком с угловым, и действительно требовала большая смелость спросить это здесь;). У меня есть директива, которая показывает время как это:

Application.Directives
.directive('theClock', function(){
    return {
        retrict: 'EA',
        templateUrl: 'partials/partial.clock.html',
        link: function(scope, elem, attrs) {

            scope.dTime = Date();
            scope.$watch( function(scp){ return Date(); }, function(newVal){ 

                    scope.dTime = newVal;
                }
            );
        }
    };
});

Я ожидаю, что время обновило бы каждый цикл $digest, но это не делает. Я знаю, что использование setInterval ot , $timeout является другим способом сделать это, но я действительно не хочу часы, я хочу понять, почему обновления не происходит. BTW, которые я действительно называл $apply() после проверки , $$phase - не помог

Спасибо.

2
nl ja de
@ValentynShybanov - Да это действительно обновляет, если вы изменяете входное значение, но isn' t $digest, называемый периодически тем более, что я установил наблюдателя? Дополнительно даже требование к $apply (), кажется, не помогает.
добавлено автор Ya. Perelman, источник
@ValentynShybanov - Да это действительно обновляет, если вы изменяете входное значение, но isn' t $digest, называемый периодически тем более, что я установил наблюдателя? Дополнительно даже требование к $apply (), кажется, не помогает.
добавлено автор Ya. Perelman, источник
Странный... просто импортировал ваш код к Plnkr и дата обновлена каждый $digest (просто изменяют входное значение, чтобы проверить - каждая дата нажатия клавиши обновляется),
добавлено автор Valentyn Shybanov, источник
Я как раз собирался задать тот же самый вопрос. Так как я создал перебор I' ll помещают его в комментарий: plnkr.co/edit/ehud1hFP6opyrnNWvbjA? p=preview (таким образом, когда эта проблема повторно появляется в месяцах, чтобы прибыть I' у ll есть контрольная точка)
добавлено автор Michal Stefanow, источник

4 ответы

Функция $watch сравнивает объекты ссылкой по умолчанию, которая быстрее и прекрасна для последовательности/числовых значений, но не будет работать на сложные объекты как Дата - Дата может измениться, но это всегда - тот же самый объект Даты, таким образом, ссылка не изменяется.

Это должно избежать тяжелых тестов на равенство на гигантских множествах.

Теперь, в то время как это может работать (отметьте третий параметр набора функции $watch к истинному):

scope.dTime = new Date();
scope.$watch( function(scp){ return new Date(); }, function(newVal){ 

  scope.dTime = newVal;
  }, true
);

Это, вероятно, вызовет событие изменения каждый раз, когда это получает голоса функции $watch (значение каждого цикла приложения)

Если вы хотите, если вызывать каждую секунду, возвратите секунды из Даты() с чем-то как возвращение Math.floor (новая Дата() .valueOf ()/1000). Тогда набор dTime, как вы желаете.

Обновление

В то время как проверка angular работала бы с дата возвращения() , проблема происходит из-за грязной системы проверки angular - это только проверит функции $watch, когда изменение будет вызвано на модели (значение модели, определенной в $scope).

Это Plnkr, приданный форму вилки от Валентина Шыбанова, может служить примером - функция тактового генератора вызывает изменение на модели, и то изменение вызывает функцию $watch.

ALSO, notice this version, that uses window.setTimeout. It can only work using an $apply method to notify angularJS that a change has occured.

5
добавлено
Вы, вероятно, правильны, который $watch сравнивает ссылкой, которая является, почему я обернул Дату() в стороне моя собственная функция. Так как Дата() без "нового" просто возвращает последовательность (и различная последовательность каждый раз), я ожидаю, что мое требование назад, чтобы обновить объем нужно назвать. Кроме того, ваш код не обновил показанное время. Спасибо так или иначе.
добавлено автор Ya. Perelman, источник
Это делает - просто проверил @Valentyn Shybanov' s Plnkr. Проблема - angular' s грязный процесс проверки. Это проверяет зарегистрированные ценности в различный $scope, и только действует, когда что-то изменяется.
добавлено автор Tiago Roldão, источник
Да, только, и не, это doesn' t. Если вы хотите, чтобы внешнее событие имело влияние на ваше angularJS приложение, необходимо сказать ему, что что-то произошло (использование метода $apply)
добавлено автор Tiago Roldão, источник
btw, мозговое замораживание: в моем оригинальном ответе я полностью забывал, какая Дата() на самом деле возвращает ^^
добавлено автор Tiago Roldão, источник

Функция $watch сравнивает объекты ссылкой по умолчанию, которая быстрее и прекрасна для последовательности/числовых значений, но не будет работать на сложные объекты как Дата - Дата может измениться, но это всегда - тот же самый объект Даты, таким образом, ссылка не изменяется.

Это должно избежать тяжелых тестов на равенство на гигантских множествах.

Теперь, в то время как это может работать (отметьте третий параметр набора функции $watch к истинному):

scope.dTime = new Date();
scope.$watch( function(scp){ return new Date(); }, function(newVal){ 

  scope.dTime = newVal;
  }, true
);

Это, вероятно, вызовет событие изменения каждый раз, когда это получает голоса функции $watch (значение каждого цикла приложения)

Если вы хотите, если вызывать каждую секунду, возвратите секунды из Даты() с чем-то как возвращение Math.floor (новая Дата() .valueOf ()/1000). Тогда набор dTime, как вы желаете.

Обновление

В то время как проверка angular работала бы с дата возвращения() , проблема происходит из-за грязной системы проверки angular - это только проверит функции $watch, когда изменение будет вызвано на модели (значение модели, определенной в $scope).

Это Plnkr, приданный форму вилки от Валентина Шыбанова, может служить примером - функция тактового генератора вызывает изменение на модели, и то изменение вызывает функцию $watch.

ALSO, notice this version, that uses window.setTimeout. It can only work using an $apply method to notify angularJS that a change has occured.

5
добавлено
Вы, вероятно, правильны, который $watch сравнивает ссылкой, которая является, почему я обернул Дату() в стороне моя собственная функция. Так как Дата() без "нового" просто возвращает последовательность (и различная последовательность каждый раз), я ожидаю, что мое требование назад, чтобы обновить объем нужно назвать. Кроме того, ваш код не обновил показанное время. Спасибо так или иначе.
добавлено автор Ya. Perelman, источник
Это делает - просто проверил @Valentyn Shybanov' s Plnkr. Проблема - angular' s грязный процесс проверки. Это проверяет зарегистрированные ценности в различный $scope, и только действует, когда что-то изменяется.
добавлено автор Tiago Roldão, источник
Да, только, и не, это doesn' t. Если вы хотите, чтобы внешнее событие имело влияние на ваше angularJS приложение, необходимо сказать ему, что что-то произошло (использование метода $apply)
добавлено автор Tiago Roldão, источник
btw, мозговое замораживание: в моем оригинальном ответе я полностью забывал, какая Дата() на самом деле возвращает ^^
добавлено автор Tiago Roldão, источник

"Я хочу понять, почему обновления не происходит".

Я думаю эта картина (от Концептуальная страница Обзора) объясняет это лучше всего:

Angular event loop

Список $watch не исследован, если $apply() не называют. $apply - то, как мы входим в "петлю $digest". Многие (все?) Угловые встроенные директивы автоматически называют $apply (таким образом, мы не имеем к). Например, как @Tiago уже упомянутый, изменяя связанную собственность $scope (внутри Угловой) приведет к называемому $apply. Мы можем также явно назвать $apply сами (например, из сторонней функции обратного вызова библиотеки мы определяем - если мы не назовем $apply здесь, мы не войдем в петлю $digest).

Нижняя строка: если мы не входим в синюю коробку ("Угловой контекст выполнения"), список $watch не исследован - таким образом, грязная проверка не выполняется.

2
добавлено

"Я хочу понять, почему обновления не происходит".

Я думаю эта картина (от Концептуальная страница Обзора) объясняет это лучше всего:

Angular event loop

Список $watch не исследован, если $apply() не называют. $apply - то, как мы входим в "петлю $digest". Многие (все?) Угловые встроенные директивы автоматически называют $apply (таким образом, мы не имеем к). Например, как @Tiago уже упомянутый, изменяя связанную собственность $scope (внутри Угловой) приведет к называемому $apply. Мы можем также явно назвать $apply сами (например, из сторонней функции обратного вызова библиотеки мы определяем - если мы не назовем $apply здесь, мы не войдем в петлю $digest).

Нижняя строка: если мы не входим в синюю коробку ("Угловой контекст выполнения"), список $watch не исследован - таким образом, грязная проверка не выполняется.

2
добавлено
Angular — русскоговорящее сообщество
Angular — русскоговорящее сообщество
3 960 участник(ов)

Общаемся на темы Angular 4+, его экосистемы, TypeScript, NativeScript и т.д. По вопросам SSR, Angular Universal @angular_universal_ru См. также: @typescript_ru, @react_js, @nodejs_ru, @js_ru Вакансии и поиск работы: @javascript_jobs

Angular.js (1.x) — русскоговорящее сообщество
Angular.js (1.x) — русскоговорящее сообщество
704 участник(ов)

Общаемся и обсуждаем темы, посвященные Angular 1.x и экосистеме.

AngularJS, Javascript
AngularJS, Javascript
370 участник(ов)

Angularjs russian chat