在Angular.js中使用ngModel中的表达式

Using expressions in ngModel in Angular.js

本文关键字:ngModel 表达式 Angular js      更新时间:2023-09-26

给出控制器内部的代码:

$scope.entity = {
  firstName: 'Jack',
  lastName: 'Bauer',
  location: {
    city: 'New York'
  }
};
$scope.path = 'location.city';

如何动态绑定ngModelpath指定的entity的属性?

我试过这样做,但是没有用:

<input ng-model="'entity.' + path">

Slava,我不太确定这是不是一个好主意。但无论如何,您需要通过将此属性添加到您的输入ng-model-options="{ getterSetter: true }来使您的模型getterSetter意识到。然后你需要在你的控制器中有一个函数,用一个字符串构建一个getterSetter。

<input type="text" ng-model="propertify('entity.' + path)" ng-model-options="{ getterSetter: true }">

这就是最终模板的样子。

幸运的是,angular有一个$parse服务,它让这变得容易得多。所以像这样的东西需要在你的控制器中,或者在注入的服务中更好。

  $scope.propertify = function (string) {
      var p = $parse(string);
      var s = p.assign;
      return function(newVal) {
          if (newVal) {
              s($scope,newVal);
          }
          return p($scope);
      } ;
  };

将返回一个getter-setter函数,该函数将为您处理此操作。

更新

不像预期的那样工作,值显示正确,但无法更改。Sander在这里提供了正确的解决方案。


<标题>错误的解决方案

哇,不小心解决了:

<input type="text" ng-model="$eval('entity.' + path)">

这是Plunk。

我希望它能帮助到别人。

如果希望绑定到嵌套属性,可以稍微修改一下括号符号。你必须分割路径到属性:

<input ng-model="entity[locationKey][cityKey]"/>

控制器:

$scope.locationKey = 'location';
$scope.cityKey = 'city';

参见js fiddle

在阅读和使用Sander Elias的答案后,我正在使用这个,但遇到了另一个问题。

当将他的结果与<input>中的ng-required="true"合并时,您不能清空字段,因为当字段为空时,newVal被传递为undefined

经过更多的研究,我在GitHub上发现了一个解决这个问题的问题。

Sander的答案和GitHub的答案是这样的:

$scope.propertify = function (string) {
    var property = $parse(string);
    var propAssign = property.assign;
    return function (newVal) {
        if (arguments.length) {
            newVal = angular.isDefined(newVal)?  newVal : '';
            propAssign($scope, newVal);
        }
        return property($scope);
    };
};

argument.length反映了传递给getter/setter的值的数量,在get上是0,在set上是1

除此之外,我添加了angular.isDefined()作为Sumit在评论中建议的,也保存false和空("")值。

这是一个更新的Plunker