【问题标题】:Dynamically assign ng-model动态分配 ng-model
【发布时间】:2012-12-20 10:53:59
【问题描述】:

我正在尝试从对象数组生成一组复选框。我的目标是让复选框将它们的 ng-model 动态映射到将提交到数组中的新对象的属性。

我的想法是这样的

<li ng-repeat="item in items">
    <label>{{item.name}}</label>
    <input type="checkbox" ng-model="newObject.{{item.name}}">
</li>

这不起作用,正如在这个 JSFiddle 上看到的那样:

http://jsfiddle.net/GreenGeorge/NKjXB/2/

有人可以帮忙吗?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    <!DOCTYPE html>
    <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <body>
    
        <div ng-app="myApp" ng-controller="myCtrl">
            <form name="priceForm" ng-submit="submitPriceForm()">
                <div ng-repeat="x in [].constructor(9) track by $index">
                    <label>
                        Person {{$index+1}} <span class="warning-text">*</span>
                    </label>
                    <input type="number" class="form-control" name="person{{$index+1}}" ng-model="price['person'+($index+1)]" />
    
                </div>
                <button>Save</button>
            </form>
        </div>
    
        <script>
            var app = angular.module('myApp', []);
            app.controller('myCtrl', function ($scope) {
                $scope.price = [];
                $scope.submitPriceForm = function () {
                    //objects be like $scope.price=[{person1:value},{person2:value}....]
                    console.log($scope.price);
                }
            });
        </script>
    </body>
    </html>

    【讨论】:

      【解决方案2】:

      使用 Angular 1.3,您可以使用 ng-model-options 指令动态分配模型,或绑定到表达式。

      这里有个小插曲:http://plnkr.co/edit/65EBiySUc1iWCWG6Ov98?p=preview

      <input type="text" ng-model="name"><br>
      <input type="text" ng-model="user.name" 
      ng-model-options="{ getterSetter: true }">
      

      更多关于ngModelOptions的信息在这里:https://docs.angularjs.org/api/ng/directive/ngModelOptions

      【讨论】:

      • 如果我遗漏了什么,请原谅我,但您的 plunk 似乎没有包含动态模型分配。 ngModelOptions 显然不会支持这一点。你能澄清一下吗?因为如果它确实如此,那将是非常有用的,事实上,以这种方式工作......
      • @XMLilley "getterSetter:确定是否将绑定到 ngModel 的函数视为 getter/setter 的布尔值。"
      • 感谢 Rob 引起我的注意,我已更新我的答案并链接到你的答案。
      【解决方案3】:

      这是我支持更深层次表达的方法,例如'model.level1.level2.value'

      <input class="form-control" ng-model="Utility.safePath(model, item.modelPath).value">
      

      其中 item.modelPath = 'level1.level2' 和 Utility(model, 'level1.level2') 是返回model.level1.level2的效用函数

      【讨论】:

      • 你能详细说明它是如何工作的吗? Utility.safePath 返回什么以便您可以使用 .value?
      • Utility.safePath 返回由路径字符串指定的嵌套变量的值。例如level1.level2 指的是model.level1.level2。
      【解决方案4】:

      编辑 正如在使用 ng-change 的 cmets 中正确指出的那样,需要事先存在“虚拟”ng-model。然而,应该注意的是,显然在 1.3 中,框架已经提供了所需的选项。请在下方查看https://stackoverflow.com/a/28365515/3497830/编辑

      以防你像我一样在一个简单的案例中遇到更复杂的任务,这是我想出的将任意表达式动态绑定到 ng-model 的解决方案:http://plnkr.co/edit/ccdJTm0zBnqjntEQfAfx?p=preview

      方法:我创建了一个指令 dynamicModel,它采用标准角度表达式,对其进行评估并通过 ng-model 和 $compile 将结果链接到范围。

      var app = angular.module('plunker', []);
      
      app.controller('MainCtrl', function($scope) {
        $scope.data = {};
        $scope.testvalue = 'data.foo';
        $scope.eval = $scope.$eval;
      });
      
      var app = angular.module('plunker', []);
      
      app.controller('MainCtrl', function($scope) {
        $scope.data = {};
        $scope.testvalue = 'data.foo';
        $scope.eval = $scope.$eval;
      });
      
      app.directive('dynamicModel', ['$compile', function ($compile) {
          return {
              'link': function(scope, element, attrs) {
                  scope.$watch(attrs.dynamicModel, function(dynamicModel) {
                      if (attrs.ngModel == dynamicModel || !dynamicModel) return;
      
                      element.attr('ng-model', dynamicModel);
                      if (dynamicModel == '') {
                          element.removeAttr('ng-model');
                      }
      
                      // Unbind all previous event handlers, this is 
                      // necessary to remove previously linked models.
                      element.unbind();
                      $compile(element)(scope);
                  });
              }
          };
      }]);
      

      用法很简单 dynamic-model="angularExpression" 其中 angularExpression 生成一个字符串,用作 ng-model 的表达式。

      我希望这可以避免有人不得不提出这个解决方案的麻烦。

      问候, 贾斯图斯

      【讨论】:

      • 你是救生员。在找到这篇文章之前我几乎绝望了。
      • 你能说得更具体一点吗?您尝试了什么,发生了什么?
      • 这是一个极具竞争力的解决方案。你让我摆脱了一个非常棘手的问题 - 谢谢!
      • ng-change 不适用于此。如果您查看角度源,则 ngChange 指令将 ngModel 作为必需指令。快速搜索显示只有 ngChange 和 ngList 有这个问题。所有其他指令似乎都将 ngModel 作为可选控制器。我通过使用 dynamic-model 指令向任何元素添加 ng-model="dummyValue" 来解决这个问题。由于对动态模型的更改调用 $compile,ngChange 和任何其他使用 ng-model 值的指令都会正确更新。
      • 这是一个更强大的解决方案,当您不需要观察动态模型值的变化时 - stackoverflow.com/a/32096328/887092
      【解决方案5】:

      这应该会给你想要的结果:

      <input type="checkbox" ng-model="newObject[item.name]">
      

      这是一个有效的 plunk:http://plnkr.co/edit/ALHQtkjiUDzZVtTfLIOR?p=preview

      【讨论】:

      • 嗯实际上这确实给了我' ',这是我缺少的东西吗?
      • 嗯,奇怪,刚刚添加了一个活生生的例子(plunker,因为出于某种原因 jsFiddle 今天不在我身边工作)。
      • 啊,是的,我习惯于在 php 中思考,并期望实际标记更改为名称,它起作用了。谢谢!
      • 太棒了,正是我想要的。我喜欢 Angular!
      • 它在 Angular 2 中也很有效。但是还有多维对象的解决方案吗?在您的示例中,如果 item.name 有时应指向 newObject['x'],有时应指向 newObject['x']['y']
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-23
      • 2015-06-09
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 1970-01-01
      相关资源
      最近更新 更多