Reputation: 4202
I would like to change which variables to watch.
JS:
var app = angular.module('myApp', []);
app.controller('MainController',
function($scope) {
$scope.current = null;
$scope.select = function(item) {
$scope.current = item;
};
var watch = ['current'];
$scope.$watchGroup(watch, function() { // This does not work
if ($scope.current !== null) {
watch = ['current'];
Array.prototype.push.apply(watch, $scope.current.watch);
$scope.current.callBack();
}
});
$scope.list = [
{
name: 'test-A',
watch: ['a'],
callBack: function() {
$scope.value = 2 * $scope.a;
}
},
{
name: 'test-B',
watch: ['b'],
callBack: function() {
$scope.value = 3 * $scope.b;
}
}
];
});
HTML:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="[email protected]" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="jquery" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js"></script>
<script data-require="[email protected]" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script data-require="[email protected]" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{current != null ? current.name : 'DropDown'}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="item in list">
<a href="javascript:void(0)" ng-click="select(item)">{{item.name}}</a>
</li>
</ul>
</div>
When "test-A" is selected, result is 2 times of A.
<br> When "test-B" is selected, result is 3 times of B.
<br>
<br>
<br>
<form class="form-inline">
<div class="form-group">
<label>A</label>
<input type="text" class="form-control" ng-model="a">
</div>
<div class="form-group">
<label>B</label>
<input type="text" class="form-control" ng-model="b">
</div>
</form>
<br> result : {{value}}
<br>
</body>
</html>
This is Plunker example.
The result
should be 2 times of A
when test-A
is selected, should be 3 times of B
when test-B
is selected.
I would like to update which variables to be watched. But the way shown in the line This does not work
does not work. This $watchGroup
only fires when current
is changed. I would like to fire this $watchGroup
when current
or a
is changed in case test-A
is selected, and when current
or b
is changed in case test-B
is selected.
I know $scope.$watchGroup(['a', 'b', 'current'], ...
works. But I do not like to fire this $watchGroup
when test-A
is selected and b
is changed and vice versa.
How can I update which variables to be watched?
Upvotes: 0
Views: 69
Reputation: 2534
Change the line:
$scope.$watchGroup(watch, function() {
as below:
$scope.$watch('current', function() {
The reason behind this is the current
value is changed when you clicked on menu. var watch = ['current'];
is different variable and this one is not changed when you click on menu. To work properly watch
, you need to point to the correct variable, in your case, $scope.current
is the correct variable.
// Code goes here
var app = angular.module('myApp', []);
app.controller('MainController',
function($scope) {
$scope.current = null;
$scope.select = function(item) {
$scope.current = item;
};
var watch = ['current'];
$scope.$watch('current', function() {
if ($scope.current !== null) {
watch = ['current'];
Array.prototype.push.apply(watch, $scope.current.watch);
$scope.current.callBack();
}
});
$scope.list = [
{
name: 'test-A',
watch: ['a'],
callBack: function() {
$scope.value = 2 * $scope.a;
}
},
{
name: 'test-B',
watch: ['b'],
callBack: function() {
$scope.value = 3 * $scope.b;
}
}
];
});
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link data-require="[email protected]" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="jquery" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.slim.min.js"></script>
<script data-require="[email protected]" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script data-require="[email protected]" data-semver="1.6.6" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
{{current != null ? current.name : 'DropDown'}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li ng-repeat="item in list">
<a href="javascript:void(0)" ng-click="select(item)">{{item.name}}</a>
</li>
</ul>
</div>
<br>
<form class="form-inline">
<div class="form-group">
<label>A</label>
<input type="text" class="form-control" ng-model="a">
</div>
<div class="form-group">
<label>B</label>
<input type="text" class="form-control" ng-model="b">
</div>
</form>
<br> result : {{current.watch}}
<br>
</body>
</html>
Upvotes: 1
Reputation: 43
find the following code as your answer see if it helps you.
Script
var app = angular.module('myApp', []);
app.controller('MainController',
function($scope) {
$scope.current = null;
$scope.select = function(item) {
$scope.current = item;
};
var watch = ['current'];
$scope.$watchGroup(watch, function() {
if ($scope.current !== null) {
watch = ['current'];
Array.prototype.push.apply(watch, $scope.current.watch);
$scope.current.callBack();
}
});
$scope.list = [
{
name: 'test-A',
watch: [' is two times of a'],
callBack: function() {
$scope.value = (2 * $scope.a) + ($scope.current.watch);
}
},
{
name: 'test-B',
watch: [' is three times of b'],
callBack: function() {
$scope.value = (3 * $scope.b) + ($scope.current.watch);
}
}
];
});
I just concatenated ($scope.current.watch)
this with your result
See if it forked to your plnkar.
https://plnkr.co/edit/UGPe4lgJPydEeAXOc0xR?p=preview
Upvotes: 1