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

Это антипаттерн, чтобы использовать часы angular $в контроллере?

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

Некоторые сайты говорят, что использование $watch на контроллере категорически неверно:

НЕ используйте $watch в контроллере. Трудно проверить и совершенно ненужно почти в каждом случае. Используйте метод в области, чтобы обновить значения (ы), которые часы меняют.

Другие кажутся прекрасными, если вы сами очищаете себя:

Функция $watch сама возвращает функцию, которая будет отпереть $watch при вызове. Итак, когда часы $watch больше не нужны, мы просто вызываем функцию, возвращаемую $watch.

Есть вопросы qaru.site/info/182070/... и другие уважаемые сайты, которые, как говорят, правы что использование $watch в контроллере - отличный способ заметить изменения в поддерживаемой angular -сервисной модели.

https://github.com/angular/angular.js/wiki/Best-Practices сайт, который, я думаю, мы можем дать немного больше веса, прямо говорит, что $scope. $watch следует замените необходимость в событиях. Однако для сложного SPA, который обрабатывает более 100 моделей и конечных точек REST, выбор использования $watch для предотвращения событий с $broadcast/$emit может закончиться лотами часов. С другой стороны, если мы не используем $watch, для нетривиальных приложений мы заканчиваем тонны спагетти событий.

Это потерять/потерять ситуацию? Это ложный выбор между событиями и часами? Я знаю, что вы можете использовать двухстороннюю привязку для многих ситуаций, но иногда вам просто нужен способ прослушивания изменений.

ИЗМЕНИТЬ

Комментарий Илана Фрумера заставил меня переосмыслить то, о чем я прошу, поэтому, возможно, вместо того, чтобы просто спросить, хорошо ли/плохо использовать часовые часы в контроллере, позвольте мне задать вопросы следующим образом:

Какая реализация, скорее всего, создаст узкое место производительности? Наличие контроллеров для прослушивания событий (которые должны были транслироваться/выбрасываться) или настройки $watch -es в контроллерах. Помните, крупномасштабное приложение.

Какая реализация сначала создает головную болью обслуживания: $watch -es или события? Возможно, существует связь (тугая/свободная) в любом случае... наблюдатели за событиями должны знать, что слушать, а $watch -es по внешним значениям (например, MyDataService.getAccountNumber()) должны знать о вещах, происходящих вне их $сфера.

** EDIT через год **

Angular сильно изменился/улучшился с тех пор, как я задал этот вопрос, но я все еще получаю +1, поэтому я подумал, что хочу упомянуть, что при просмотре командного кода angular я вижу шаблон, когда он приходит к наблюдателям в контроллерах (или директивах, где есть область, которая уничтожается):

$scope.$on('$destroy', $scope.$watch('scopeVariable', functionIWantToCall)); Что это делает, что возвращает функция $watch - функция, которую можно вызвать, чтобы отменить регистрацию наблюдателя - и передать ее обработчику события, когда контроллер будет уничтожен. Это автоматически очищает наблюдателя.

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

Спасибо!

4b9b3361

Ответ 1

Я использую оба, потому что, честно говоря, я рассматриваю их как разные инструменты для разных задач.

Я приведу пример из приложения, которое я создал. У меня была сложная служба WebSocket, которая получала динамические модели данных с сервера веб-сокетов. Сама услуга не волнует, как выглядит модель, но, конечно же, контроллер уверен.

Когда инициируется контроллер, он настроил $watch на объект данных службы, чтобы он знал, когда появился конкретный объект данных (например, ожидая существования Service.data.foo). Как только эта модель появилась, он смог привязать к нему и привязать к нему двухстороннюю привязку данных, часы стали устаревшими и были уничтожены.

С другой стороны, служба также отвечала за вещание определенных событий, потому что иногда клиент получал от сервера буквальные команды. Например, Сервер может потребовать, чтобы клиент отправил некоторые метаданные, которые были сохранены в "$ rootScope" во всем приложении. a .on() был настроен в $rootScope во время шага module.run() для прослушивания этих команд с сервера, сбора необходимой информации от других служб и вызова службы WebSocket обратно для отправки данных по запросу. В качестве альтернативы, если бы я сделал это с помощью $watch(), мне понадобилось бы установить какую-то произвольную переменную для просмотра, например metadataRequests, которую мне нужно будет увеличивать каждый раз, когда я получаю запрос. A broadcast обеспечивает одно и то же, не имея постоянной памяти, как наша переменная.

По существу, я использую $watch(), когда есть определенное значение, которое я хочу увидеть изменение (особенно, если мне нужно знать значения до и после), и я использую события, если есть более высокоуровневые условия, которые были соблюдены контроллерами.

Что касается производительности, я не мог сказать вам, какой из них будет узким местом, но я чувствую, что думать об этом таким образом позволит вам использовать сильные стороны каждой функции, где они сильнейшие. Например, если вы используете $on() вместо $watch() для поиска изменений в данных, у вас не будет доступа к значениям до и после изменения, что может ограничить то, что вы пытаетесь сделать.

Ответ 2

Вся эта двусторонняя привязка данных является $watch по любому свойству scope, которое вы передаете ng-model, у которого есть контроллер, который позволяет другим директивам, таким как input и form синхронизировать ng-model, чтобы отобразить представление при изменении. Это определяется их регистрацией событий в DOM.

В сущности, ng-model $watch сравнивает значение в модели со значением, которое оно имеет внутри. Значение, которое оно внутренне задано, поддерживает директивы (ввод, форма и т.д.).

IMHO Единственные "события", на которые вы должны реагировать в приложении angular, создаются пользователем (т.е. события DOM). Они решаются с помощью директив DOM и ng-model, связанных с модой .model Также естественно существует async, для которого angular предоставляет $q, для которого обратные вызовы вызывают $digest.

Что касается производительности, в нем хорошо сказано в документах angular. Его запуск выполняется на каждом $digest. Так что сделайте это быстро. Что такое $digest? angular перемещает все ваши активные области. В каждой области есть часы. который он выполняет. и выполняет сравнения в них. Если есть различия, он снова запустится. (следующий цикл). Это не так просто, потому что его оптимизированный, но все ваш "angular код" выполняется в этом цикле $digest. Многие директивы могут ссылаться на дайджест с помощью scope.$apply(...) Это приведет к тому, что часы любого значения, которое они изменили, заметят и сделают свое дело.

Итак, ваш оригинальный вопрос. Это анти-шаблон? Абсолютно нет, если вы знаете, как его использовать. Хотя я бы просто использовал ng-модель. Просто потому, что у него было 1.2.10+ итераций довольно умных людей, работающих над ним... Вся другая "реактивная способность" вашего приложения может обрабатываться $q, $timeout и т.п.

Ответ 3

Я думаю, что у всех у них есть свое место, и для меня было бы трудно сказать, что нельзя использовать их для других.

Связывание данных всегда должно использоваться для синхронизации вашей модели данных с изменениями из представления. Я думаю, мы все можем согласиться на это.

Я думаю, что использование часов на контроллере для запуска некоторых действий на основе изменения данных является полезным. Подобно просмотру сложной модели данных для расчета общей суммы для счета-фактуры. Или смотреть модель, чтобы вызвать ее как грязную.

Я использовал широковещательную /emit/on при отправке сообщения или указание какого-либо изменения из одной области действия в другую, которая может быть на несколько слоев. Я создал настраиваемую директиву, в которой широковещательное событие использовалось как крючок для принятия каких-либо действий в контроллере.