AngularJS: автоматически обнаруживает изменения в модели

Предположим, я хотел сделать что-то вроде автоматического запуска некоторого кода (например, сохранения данных на сервер) при изменении значений модели. Единственный способ сделать это, установив что-то вроде ng-change на каждый элемент управления, который может изменить модель?

То есть, с представлениями, вещи меняются правильно, поскольку модель изменяется без необходимости явно подключать что-либо. Есть ли аналог для возможности запуска кода, который сохраняется на сервере? Что-то вроде

myModel.on('change', function() {
  $.post("/my-url", ...);
});

как вы могли бы видеть что-то вроде позвоночника.

Ответ 1

В представлениях с {{}} и/или ng-модель, Angular настраивает $watch() es для вас за кулисами.

По умолчанию $watch сравнивается по ссылке. Если вы установите третий параметр в $watch на true, Angular вместо этого будет "мелким" наблюдать за объектом за изменениями. Для массивов это означает сравнение элементов массива, для карт объектов это означает просмотр свойств. Таким образом, это должно делать то, что вы хотите:

$scope.$watch('myModel', function() { ... }, true);

Обновление: Angular v1.2 добавлен новый метод для этого, ` $watchCollection():

$scope.$watchCollection('myModel', function() { ... });

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

Ответ 2

И если вам нужно стильно стилизовать элементы формы в соответствии с ним (измененные/не измененные) динамически или проверить, действительно ли некоторые значения были изменены, вы можете использовать следующий модуль, разработанный мной: https://github.com/betsol/angular-input-modified

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

Вы можете настроить следующие часы: $scope.$watch('myForm.modified', handler), и ваш обработчик будет вызван, если некоторые элементы формы фактически содержат новые данные или если они перешли в исходное состояние.

Кроме того, вы можете использовать свойство modified для отдельных элементов формы, чтобы фактически уменьшить количество данных, отправленных на сервер через вызов AJAX. Нет необходимости отправлять неизменные данные.

В качестве бонуса вы можете вернуть форму в исходное состояние с помощью метода вызова reset().

Здесь вы можете найти демо-версию модуля: http://plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

Ура!