AngularJS отслеживает свойство объекта в массиве объектов
У меня есть этот data
в моем контроллере
$scope.data = {
home: {
baseValue: "1",
name: "home"
},
contact: {
baseValue: "2",
name: "contract"
}
// a lot more options
};
с некоторым html следующим образом:
<section class="content row" ng-repeat="item in data">
{{item.name}}
....
</section>
Теперь я хочу знать, когда изменяется baseValue
, но из-за того, что я использую объекты внутри переменной данных, я не могу watch
свойство более простым способом.
Я пробовал что-то вроде этого, но мне нужно петлю весь массив
$scope.$watch('data', function (newValue, oldValue, scope) {
// some code to compare the tow arrays, line by line
}, true);
Как я могу сделать более простой $watch
, чтобы знать только при изменении baseValue
?
Похожие вопросы:
ОБНОВЛЕНИЕ 1
Я мог бы добавить индивидуальные часы для каждого объекта, чтобы знать, когда изменяется baseValue
, но это не будет хорошо, если бы у меня было число объектов n
, а не только несколько объектов, подобных этому примеру
$scope.$watch('data.home', function (newValue, oldValue, scope) {
// do some stuff with newvalue.baseValue
}, true);
$scope.$watch('data.contact', function (newValue, oldValue, scope) {
// do some stuff with newvalue.baseValue
}, true);
... // Adds more individual `watch`
Ответы
Ответ 1
В соответствии с вашим вопросом вы можете использовать ngChange для просмотра изменений baseValue
и запускать функцию.
HTML
<section class="content row" ng-repeat="item in data">
Name: {{item.name}} <br/>
BaseValue: <input type="text" ng-model="item.baseValue" ng-change="baseValueChange(item.baseValue)"/>
</section>
контроллер
$scope.baseValueChange = function(baseValue) {
console.log("base value change", baseValue);
}
Если у вас более сложная версия, которая может получить oldValue и newValue, вы можете обратиться к этому plunkr - http://plnkr.co/edit/hqWRG13gzT9H5hxmOIkO?p=preview
HTML
<section class="content row" ng-repeat="item in data">
Name: {{item.name}} <br/>
BaseValue: <input type="text" ng-init="item.oldBaseValue = item.baseValue" ng-model="item.baseValue" ng-change="baseValueChange(item.oldBaseValue, item.baseValue); item.oldBaseValue = item.baseValue"/>
</section>
контроллер
$scope.baseValueChange = function(oldVal, newVal) {
console.log("base value change", oldVal, newVal);
}
Ответ 2
Вы можете просмотреть атрибут объекта.
Таким образом, вы можете сделать что-то вроде
for(var key in $scope.data) {
if($scope.data.hasOwnProperty(key)) {
$scope.$watch("data['" + key + "'].baseValue", function(val, oldVal) {
// Do stuff
});
}
}
Не тестировалось, но идея проста.
Ответ 3
В этом сценарии нет способа обойти использование нескольких часов, другой способ сделать это - используя $watchCollection
для просмотра массива значений объекта, вы можете получить этот массив с помощью функции Object.values
.
scope.$watchCollection(function() {
return Object.values(obj);
}, function(newValues, oldValues) {
// now you are watching all the values for changes!
// if you want to fire a callback with the object as an argument:
if (angular.isFunction(scope.callback())) {
scope.callback()(obj);
}
});
Ответ 4
Я решил с этим решением:
$scope.updateFields= function(){
angular.forEach($scope.fields,function (value, key) {
value.title = value.title.toLowerCase().replace(/\s+/g,'');
})
};
$scope.$watch('fields', $scope.updateFields, true);