Reputation: 1657
I would like to try and have a generic function in my controller that I can use from my view to tell a specific variable within the scope to change to a specific value.
$scope = {
hair: {
color: 'blue',
length: '2cm'
},
mouth: 'wide',
arms: [
{
fingers: 5,
color: 'brown'
},
{
fingers: 4,
color: 'white'
}
]
}
$scope.updateVariable = function(scopeVariable, value){
scopeVariable = value;
}
<a ng-click="updateVariable(hair.color, 'red');">red hair</a>
<a ng-click="updateVariable(hair.length, '5cm');">increase hair length</a>
<a ng-click="updateVariable(mouth, 'narrow');">narrow mouth</a>
<a ng-click="updateVariable(arms[0].fingers, 4);">4 fingers</a>
It seems only the value of the variable is passed on to the function but not the reference. Is there a way for me to get the reference to the scope variable instead of its value from a function parameter? Furthermore can that be done dynamically? And by this I mean I need to pass the "path" to where this variable is located in the scope.
I am aware that this can be done with independent setter functions (i.e.: setMouth('narrow')) but let's assume for the sake of this exercise we do not know ahead of time the structure of the scope in the controller but only in the view and because of that we need a generic function that can deal with property.
Upvotes: 1
Views: 95
Reputation: 927
If you pass objects around, they will be by reference.
For instance, rather than passing hair.color back, if you sent hair back instead it would work.
So to update as well?
Set it in the click is one option .
ngclick="hair.color = 'red'"
Also you can pass properties around.
Dot notation and bracket notation with variables are the same.
So hair.color is the same as hair["color"] - the later can be dynamic. You could pass a property name and update it .
Upvotes: 1
Reputation: 1073968
It seems only the value of the variable is passed on to the function but not the reference.
Correct.
Is there a way for me to get the reference to the scope variable instead of it's value from a function parameter?
No, JavaScript simply does not have that (which is called pass by reference). Instead, you can pass the name of the variable and then use that name in your function:
<a ng-click="updateVariable('hair.color', 'red');">red hair</a>
<a ng-click="updateVariable('hair.length', '5cm');">increase hair length</a>
<a ng-click="updateVariable('mouth', 'narrow');">narrow mouth</a>
<a ng-click="updateVariable('arms[0].fingers', 4);">4 fingers</a>
then apply the techniques in this question and its answers to update $scope
from the path. Adapting the function from the answer by Alnitak to make it a setter:
Object.setByString = function(o, s, value) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
if (i == n - 1) {
o[k] = value;
return value;
}
o = o[k];
} else {
return value;
}
}
return value;
};
then
$scope.updateVariable = function(scopeVariablePath, value){
Object.setByString($scope, scopeVariablePath, value);
};
Upvotes: 1