Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS:动态设置模型名称的嵌套对象_Javascript_Angularjs - Fatal编程技术网

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');