我见过几个类似的问题,但我的问题略有不同。
我的控制器上有一个看起来像这样的对象:
$scope.data = {
foo: {bar: 1,
bas: 2},
biz: 3,
blat: 4
};
我想创建一个输入,可以将其ng模型动态分配给任何这些值。
<label>Define Model</label>
<input type="text" ng-model="input.model" />
<label>Data for {{input.model}}:</label>
<input type="text" ng-model="{{input.model}}">
理想情况下,这可以让我将“定义模型”输入设置为data.foo.bas
,“Data for data.foo.bas”输入的值为2.
我知道我可以这样做:
<label>Define Model</label>
<input type="text" ng-model="input.model" />
<label>Data for {{input.model}}:</label>
<input type="text" ng-model="data[input.model]">
但这只允许我访问biz和blat属性。有没有人有任何想法如何做到这一点?谢谢。
答案 0 :(得分:3)
您可以使用$parse
$scope.$watch('input.model', function(newVal) {
$scope.definedModel = $parse(newVal)($scope.data);
});
此处$parse
尝试匹配$scope.data
中的值并将其与definedModel
绑定
demo plunker
答案 1 :(得分:0)
你可以这样做,但只有你稍微修改数据数组的形式,这样每个模型都有自己的对象(而不仅仅是一个基元),具有一个共同的结构:
var data = {
foo: {
bar: {
value: 1
},
bas: {
value: 2
}
},
biz: {
value: 3
},
blat: {
value: 4
}
};
这样您就可以传递对象,因此ngModel
仍然可以引用(以及更改)原始对象。
然后你需要一个函数来转换类似“foo.bas”的“路径”,以返回正确的对象modified from this answer:
var getProperty = function(obj, prop) {
var parts = prop.split('.'),
last = parts.pop(),
l = parts.length,
i = 1,
current = parts[0];
if (l === 0) return obj[prop];
while((obj = obj[current]) && i < l) {
current = parts[i];
i++;
}
if(obj) {
return obj[last];
}
}
然后您必须观察input.model
变量,以确保范围的model
变量设置为正确的对象:
$scope.$watch('input.model', function(name) {
$scope.model = getProperty(data, name);
});
最后,这一切都由在范围内设置“input.model”和“model”的输入控制:
<input placeholder="Model name" ng-model="input.model" />
<input placeholder="Model value" ng-model="model.value" />
这可以是seen in action at this Plunker
修改:根据the answer from @Reza,您可以使用$parse
代替上面的getProperty
功能。使用它,观察者可以
$scope.$watch('input.model', function(name) {
$scope.model = $parse(name)(data);
});
可以看到in this Plunker。我不得不承认,使用更少的代码是一种更好的方法。
答案 2 :(得分:0)
也许尝试使用您想要的ng-model属性重新编译元素:https://gist.github.com/djdmbrwsk/9a7004492a709044e597