如何通过点分隔路径动态分配ngmodel

时间:2014-01-02 05:48:15

标签: javascript angularjs model

我见过几个类似的问题,但我的问题略有不同。

我的控制器上有一个看起来像这样的对象:

$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属性。有没有人有任何想法如何做到这一点?谢谢。

3 个答案:

答案 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