Я хочу следить за изменениями в словаре, но по какой-то причине смотреть обратный вызов не вызывается.
Вот контроллер, который я использую:
function MyController($scope) {
$scope.form = {
name: 'my name',
surname: 'surname'
}
$scope.$watch('form', function(newVal, oldVal){
console.log('changed');
});
}
Вот скрипка .
Я ожидаю, что обратный вызов $ watch будет срабатывать при каждом изменении имени или фамилии, но этого не происходит.
Как правильно это сделать?
javascript
angularjs
angularjs-scope
Владимир Сидоренко
источник
источник
Ответы:
Вызов
$watch
сtrue
третьим аргументом:По умолчанию при сравнении двух сложных объектов в JavaScript они проверяются на «ссылочное» равенство, которое спрашивает, ссылаются ли два объекта на одно и то же, а не на «значение», которое проверяет, являются ли значения всех свойств этих объектов объекты равны.
Согласно документации Angular , третий параметр предназначен для
objectEquality
:источник
true
, то будет проверяться равенство ссылок, если отслеживаемое значение является объектом или массивом. В этом случае, вы должны указать свойства явно, как$scope.$watch('form.name')
и$scope.$watch('form.surname')
form
Объект не меняется, толькоname
свойствообновленная скрипка
источник
Небольшой совет по производительности, если у кого-то есть сервис хранилища данных с парой ключ -> значение:
Если у вас есть служба с именем dataStore , вы можете обновлять временную метку всякий раз, когда изменяется ваш большой объект данных. Таким образом, вместо глубокого наблюдения за всем объектом, вы смотрите только временную метку для изменения.
И в директиве вы смотрите только метку времени, чтобы изменить
источник
newVal
,oldVal
В этом примере , являются значения временных меток не наблюдаемые объекты значения. Это не делает этот ответ недействительным, я просто думаю, что это недостаток, который стоит упомянуть.Причина, по которой ваш код не работает, заключается в том, что
$watch
по умолчанию выполняется проверка ссылок. Итак, в двух словах, убедитесь, что объект, который передается ему, является новым объектом. Но в вашем случае вы просто изменяете какое-то свойство объекта формы, а не создаете новое. Чтобы заставить его работать, вы можете передатьtrue
в качестве третьего параметра.Это будет работать, но вы можете использовать $ watchCollection, который будет более эффективным, чем $ watch, потому что
$watchCollection
будет следить за поверхностными свойствами объекта формы. Напримеристочник
Поскольку вы ищете изменения объекта формы, лучший подход к просмотру - использовать
$watchCollection
. Пожалуйста, ознакомьтесь с официальной документацией для различных характеристик производительности.источник
Попробуй это:
источник
Для тех, кто хочет наблюдать за изменением объекта в массиве объектов, мне показалось, что это работает (как и другие решения на этой странице):
источник
источник