Javascript AngularJS:动态设置模型名称的嵌套对象
我有一个包含变量名的数组,例如:Javascript AngularJS:动态设置模型名称的嵌套对象,javascript,angularjs,Javascript,Angularjs,我有一个包含变量名的数组,例如: var names = ['address.street','address.city']; 我想用这些创建输入字段,我使用的是AngularJS。没什么大不了的: <div ng-repeat="n in names"> <input type="text" ng-model="data[n]" /> </div> 顺便说一句,这并不是我想要达到的目标。 是否有一种语法可以将我引向一个对象,结果如下 {
var names = ['address.street','address.city'];
我想用这些创建输入字段,我使用的是AngularJS。没什么大不了的:
<div ng-repeat="n in names">
<input type="text" ng-model="data[n]" />
</div>
顺便说一句,这并不是我想要达到的目标。
是否有一种语法可以将我引向一个对象,结果如下
{
"address" : {
"street" : ...,
"city" : ...
}
}
请考虑我可以有一个以上的嵌套级别,这只是一个例子。
< P>我不认为应该这样访问模型。 然而,这是一个奇怪的问题,解决方法有点有趣 问题是,ng model
需要引用,并且认为Javascript发送对象的可修改副本,所以我们不能只将字符串传递给ng model
但是,数组和对象确实具有此属性。因此,解决方案是返回一个数组,其0
th元素将作为ng model
的参考。这也是令人讨厌的部分,因为您的所有对象现在都是带有“1”元素的数组
另一种解决方案是为每种情况返回一个对象,而不是一个元素数组
使用嵌入式对象的解决方案
以下是使用嵌入式对象的解决方案:在我看来,它看起来更好
因此,在控制器中:
$scope.getModel=函数(路径){
var segs=path.split('.');
var root=$scope.data;
而(分段长度>0){
var pathStep=segs.shift();
if(根的类型[pathStep]=“未定义”){
根[pathStep]=segs.length==0?{值:'}:{};
}
root=root[pathStep];
}
返回根;
}
在模板中:
你好{{{data.person.name.value}
地址:{{data.Address.value}
使用单元素数组的解决方案
以下是我能想到的最短(尽管有些粗糙)的解决方案:
因此,在控制器中:
$scope.getModel=函数(路径){
var segs=path.split('.');
var root=$scope.data;
而(分段长度>0){
var pathStep=segs.shift();
if(根的类型[pathStep]=“未定义”){
根[pathStep]=segs.length==0?['']:{};
}
root=root[pathStep];
}
返回根;
}
在模板中:
你好{{{data.person.name[0]}
地址:{{data.Address[0]}
如果您可以重新构造模型,您只需执行以下操作:
<input ng-model="getModelParent(fieldPath)[ getModelLeaf(fieldPath) ]"/>
控制器
HTML
由@musicaly\u ut提供的答案很好,但有一个明显的缺陷: 如果您正在创建一个新模型,那么它将非常有用,但是如果您有一个预定义的现有模型,无法重构为“.value”结构或数组结构,那么您将陷入 很明显我就是这样。。。(我认为@LorenzoMarcon也是如此,因为他暗示他必须“后处理”结果并将其转换为不同的格式) 最后我详细阐述了@musically_ut的解决方案:
$scope.getModelParent = function(path) {
var segs = path.split('.');
var root = $scope.data;
while (segs.length > 1) {
var pathStep = segs.shift();
if (typeof root[pathStep] === 'undefined') {
root[pathStep] = {};
}
root = root[pathStep];
}
return root;
};
$scope.getModelLeaf = function(path) {
var segs = path.split('.');
return segs[segs.length-1];
};
(注意while循环索引中的更改)
稍后,您将访问动态字段,如下所示:
<input ng-model="getModelParent(fieldPath)[ getModelLeaf(fieldPath) ]"/>
其思想是(正如@musicaly_ut的回答中所解释的),JS不能通过引用传递字符串,因此围绕它的黑客我传递父节点(因此“getModelParent”中的while循环在最后一个索引之前停止),并使用类似数组的表示法访问叶节点(从“getModelLeaf”)
希望这是有意义和有帮助的 为了更方便地解析路径,您还可以检查lodash的方法:
_.get($scope, 'model.nested.property', 'default');
_.set($scope, 'model.nested.property', 'default');
_.has($scope, 'model.nested.property');
你是说你的
$scope.data
是{“地址”:{“街道”:…,“城市”:…}
。不清楚,我试图让你从以下问题中得到答案:“请考虑我可以有一个以上的嵌套级别,这只是一个例子。”在这种情况下,我们将嵌套<代码> NG重复> /Calp> S。确实,有更好的方法来解决这个问题,但是这个问题本身是一个奇怪的问题。谢谢你的回答,我一直在寻找一种不改变初始模型阵列的方法。此外,有些元素可能没有嵌套(例如名称),有些元素可能有一个或多个嵌套(例如address.street),但我事先不知道,因此此解决方案对我的案例非常有限。我看到了您所做的努力,感谢您的详细解释。这很接近,但是输出数据对象将不同于我正在寻找的格式(您可以在我的问题中看到)。考虑到我的限制,也许你的是唯一可行的方法,在这种情况下,我可能不得不再次对结果对象进行后期处理,以将其转换为我需要的格式。@LorenzoMarcon感谢你接受了答案。我确实意识到这不是你想要的解决方案,但无论如何,这是一个值得思考的有趣问题。你有我的(+1)是为了好玩。:)谢谢roy650。这对我来说很有用,因为在音乐上,解决方案中你将得到“地址:{city:{value:{}”,但是通过上面的方法,你不会得到额外的“值:{}”。你也可以像$scope.getModelLeaf=function(path){var segs=path.split('.');返回segs.pop();};
<input ng-model="getModelParent(fieldPath)[ getModelLeaf(fieldPath) ]"/>
_.get($scope, 'model.nested.property', 'default');
_.set($scope, 'model.nested.property', 'default');
_.has($scope, 'model.nested.property');