Editing Multiple Variables Using a Single Model
Is there a way to edit three different variables using just one model? Because in the current approach it looks like only the variable value is copied to "editVar".
<div ng-controller="MyCtrl">
A: {{A}}<br/> B: {{B}} <br/> C: {{C}}<br/>
<input ng-model="editedVar"/>
<br/>
<button ng-click="switchToA()">Switch to A</button>
<button ng-click="switchToB()">Switch to B</button>
<button ng-click="switchToC()">Switch to C</button>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.A = 1;
$scope.B = 2;
$scope.C = 3;
$scope.switchToA = function()
{
$scope.editedVar = $scope.A;
};
$scope.switchToB = function()
{
$scope.editedVar = $scope.B;
};
$scope.switchToC = function()
{
$scope.editedVar = $scope.C;
};
}
source to share
You could do it in different ways, here is a simpler and drier way.
View (just keep them just as one function to change the currently edited var): -
<input ng-model="editedVar[editing]" />
<br />
<button ng-click="switchTo('A')">Switch to A</button>
<button ng-click="switchTo('B')">Switch to B</button>
<button ng-click="switchTo('C')">Switch to C</button>
Controller: -
function MyCtrl($scope) {
/*Keep the values in an object with respective property name*/
$scope.editedVar = {
A: 1,
B: 2,
C: 3
}
/*Set the default edit property*/
$scope.editing = 'A';
/*Sets the currently edited property based on what is being passed in*/
$scope.switchTo = function (prop) {
$scope.editing = prop;
};
}
You can also do this, but only with a lot of maintenance code without using an object.
View: -
<input ng-model="editedVar" ng-change="valueChange()"/>
<br/>
<button ng-click="switchTo('A')">Switch to A</button>
<button ng-click="switchTo('B')">Switch to B</button>
<button ng-click="switchTo('C')">Switch to C</button>
Controller: -
function MyCtrl($scope) {
$scope.A = 1;
$scope.B = 2;
$scope.C = 3;
var editing;
/*Change event to keep the value in sync*/
$scope.valueChange = function(){
$scope[editing] = $scope.editedVar;
}
/*Just one function*/
$scope.switchTo = function (prop) {
$scope.editedVar = $scope[editing = prop];
};
}
source to share
What you want is a two way link binding with a non primitive type, see below:
<div ng-controller="MyCtrl">
A: {{A.val}}<br/> B: {{B.val}} <br/> C: {{C.val}}<br/>
<input ng-model="editedVar.val"/>
<br/>
<button ng-click="switchToA()">Swithc to A</button>
<button ng-click="switchToB()">Swithc to B</button>
<button ng-click="switchToC()">Swithc to C</button>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.A = {val: 1};
$scope.B = {val: 2};
$scope.C = {val: 3};
$scope.switchToA = function()
{
$scope.editedVar = $scope.A;
};
$scope.switchToB = function()
{
$scope.editedVar = $scope.B;
};
$scope.switchToC = function()
{
$scope.editedVar = $scope.C;
};
}
source to share
The only limitation of @ PSL's answer is that if other code changes the value A
, B
or C
in scope, it $scope.editedVar
doesn't update correctly. Instead, the next alternative uses two clockwork mechanisms to ensure that the correct scope property is kept up to date, no matter how you changed it with editedVar
input or some other code.
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function MyCtrl($scope) {
$scope.A = 1;
$scope.B = 2;
$scope.C = 3;
var propToEdit,
deregPrevWatch;
$scope.switchTo = function(prop) {
propToEdit = prop;
// set up a watch on this property so if anything else updates it
// editedVar gets correctly updated.
// Make sure to deregister the previous watch first.
if (deregPrevWatch)
deregPrevWatch();
deregPrevWatch = $scope.$watch(prop, function(val) {
$scope.editedVar = val;
});
};
$scope.$watch('editedVar', function(newVal, oldVal) {
// skip the initialisation step
if (newVal !== oldVal)
$scope[propToEdit] = newVal;
});
// start off pointing at A
$scope.switchTo('A');
});
p {
margin: 2px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.7/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<p>A: {{A}}</p>
<p>B: {{B}}</p>
<p>C: {{C}}</p>
<input ng-model="editedVar" />
<p>
<button ng-click="switchTo('A')">Switch to A</button>
<button ng-click="switchTo('B')">Switch to B</button>
<button ng-click="switchTo('C')">Switch to C</button>
<button ng-click="A = 5">Set A to 5</button>
</p>
</div>
</div>
source to share