I do not think models should be accessed this way.
However, this was curious question and the solution is a bit fun.
The problem is that ng-model
requires a reference and thought Javascript sends modifiable copies of objects, it does not have pass-by-reference semantics and we cannot just pass a string to ng-model
.
However, arrays and objects do have this property. Hence, the solution is to return an array whose 0
th element will be the reference for ng-model
. This is also the hacky part since all your objects are now arrays with '1' element.
The other solution would be to return an object for each case instead of 1 element array.
Solution using embedded objects
Here is the solution using an embedded object: http://plnkr.co/edit/MuC4LE2YG31RdU6J6FaD?p=preview which in my opinion looks nicer.
Hence, in your controller:
$scope.getModel = function(path) {
var segs = path.split('.');
var root = $scope.data;
while (segs.length > 0) {
var pathStep = segs.shift();
if (typeof root[pathStep] === 'undefined') {
root[pathStep] = segs.length === 0 ? { value: '' } : {};
}
root = root[pathStep];
}
return root;
}
And in your template:
<p>Hello {{data.person.name.value}}!</p>
<p>Address: {{data.address.value}}</p>
<input ng-model="getModel('person.name').value" />
<input ng-model="getModel('address').value" />
Solution using single element array
Here is the shortest (albeit hacky) solution I could come up with: http://plnkr.co/edit/W92cHU6SQobot8xuElcG?p=preview
Hence, in your controller:
$scope.getModel = function(path) {
var segs = path.split('.');
var root = $scope.data;
while (segs.length > 0) {
var pathStep = segs.shift();
if (typeof root[pathStep] === 'undefined') {
root[pathStep] = segs.length === 0 ? [ '' ] : {};
}
root = root[pathStep];
}
return root;
}
And in your template:
<p>Hello {{data.person.name[0]}}!</p>
<p>Address: {{data.address[0]}}</p>
<input ng-model="getModel('person.name')[0]" />
<input ng-model="getModel('address')[0]" />
$scope.data
is{ "address" : { "street" : ..., "city" : ... } }
. Its not clear – Maxim Shoustin Nov 21 '13 at 11:52