Watch multiple $scope attributes
Starting from AngularJS 1.3 there's a new method called $watchGroup
for observing a set of expressions.
$scope.foo = 'foo';
$scope.bar = 'bar';
$scope.$watchGroup(['foo', 'bar'], function(newValues, oldValues, scope) {
// newValues array contains the current values of the watch expressions
// with the indexes matching those of the watchExpression array
// i.e.
// newValues[0] -> $scope.foo
// and
// newValues[1] -> $scope.bar
});
AngularJS $watch multiple items
I would suggest to use $watchGroup
So your watchers should look like
$scope.$watchGroup(['height', 'chest', 'waist', 'hips', 'thighs'], function() {
$scope.$storage.userData.bodyType = ({'height': $scope.height,'chest': $scope.chest,'waist': $scope.waist,'hips': $scope.hips,'thighs': $scope.thighs,'bodyType': bodyType});
});
link to the documentation: $watchGroup
How can I $watch multiple values
Angular has a built-in way to invoke the same function when any of specified expressions change - with $watchGroup
:
$scope.$watchGroup(["foo", "bar"], function(newValues, oldValues){
// do something when either $scope.foo or $scope.bar changes
});
Watch on all attributes of an object in AngularJS
Use the third argument of $watch, like this :
$scope.$watch('content', function(){
// do some work
}, true);
If this is true, the expression is evaluated for object equality, which means properties are included. Otherwise it's just evaluated for reference.
Watch attribute-values of multiple elements without directive?
<div ng-app="myApp" ng-controller="myCtrl">
<input type="text" ng-model="value">
<p>Current value is: {{value}}</p>
<ul>
<li ng-repeat="option in options">
<ul decisionIndex="{{value}}">
<li ng-click="setValue(0)">Edit {{option.name}}</li>
<li ng-click="setValue(1)">Choose {{option.name}}</li>
<li ng-click="setValue(2)">Delete {{option.name}}</li>
</ul>
</li>
</ul>
</div>
Controller:
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.value = 0; //Set initial value, or just declare it;
$scope.options = [
{name: "Bob"},
];
$scope.setValue = function(a){
$scope.value = a;
}
$scope.$watch('value', function(newVal, oldVal){
console.log(newVal);
})
}]);
watch on directive attribute
Please check this working code.
var app = angular.module('myApp', []);
app.directive('foo', function() { return { restrict: 'EA', scope: { max: '@', }, link: function(scope, element, attrs) { /*scope.$watch(attrs.max, function() { alert('max changed to ' + max); });*/
attrs.$observe('max', function(val) { alert('max changed to ' + val); }); } }});
app.controller('MyController', ['$scope', function($scope) { $scope.title = 'Hello world'; $scope.max = 4; $scope.changeMax = function() { $scope.max += Math.floor(Math.random() * 10); }}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js" ></script> <div ng-controller='MyController' ng-app="myApp"> <div>{{title}}</div> <input id='txt' type='text' max="{{max}}" value="{{max}}" foo/> <input type="button" ng-click="changeMax()" value='change max' /> </div>
What happens when $scope.$watch expression depends on multiple variables?
Does the watch end up watching both
service.properties
andservice.selectedProperty
?
In fact, it is watching neither, only the result of evaluating the expression as a whole. I explain:
Angular watches use a dirty checking principle: if the expression as a whole is evaluated to be something else than when it was last evaluated, a change has happened, and the associated handlers are run. (This behaviour is more apparent when you use the form of $watch
which takes a function as its first argument - returning the value to be watched.)
That means that technically there could exist a situation where service.properties[service.selectedProperty]
is evaluated the same as before, but service.properties
, the associative object, and service.selectedProperty
, the property key have both (or either of them) changed in the meantime - yet, the expression is evaluated to be the same. In such cases, the change event is not triggered.
For example, given:
var myObj = {
a: 123,
b: 123
};
var key = 'a';
the value of the expression myObj[key]
will stay the same even if you change key
to be 'b'
instead of 'a'
.
As long as the expression evaluates to be the same, from the viewpoint of angular, nothing has changed. And for most intents and purposes, nor should it matter to you - if it does, your watch expression is set up improperly, and you probably want to watch a more generic expression.
Related Topics
How to Pass Parameters in Computed Properties in Vue.Js
Check If Jquery Has Been Loaded, Then Load It If False
How to Redirect to an External Url from Angular2 Route Without Using Component
Getting "Typeerror: Failed to Fetch" When the Request Hasn't Actually Failed
Check Whether an Array Exists in an Array of Arrays
Is It Safe to Assume Strict Comparison in a JavaScript Switch Statement
How to Replace Selected Text with HTML in a Contenteditable Element
How to Create Document Objects with JavaScript
Jquery Dom Changes Not Appearing in View Source
Why Define an Anonymous Function and Pass It Jquery as the Argument
How to Reset <Input Type = "File">
Limit Concurrency of Promise Being Run
Onclick Event Getting Called Automatically
How to Add/Subtract Dates with JavaScript
How to Smoothly Scroll to an Element in Pure JavaScript
Where to Save a Jwt in a Browser-Based Application and How to Use It