动态分配ng模型


82

我正在尝试从对象数组生成一组复选框。我的目标是使复选框动态地将其ng模型映射到将要提交到数组中的新对象的属性。

我的想法是

<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/

有人可以帮忙吗?

Answers:


146

这应该给您想要的结果:

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

这是一个工作正常的小伙伴:http ://plnkr.co/edit/ALHQtkjiUDzZVtTfLIOR? p= preview


1
嗯,实际上这确实给了我'<input ng-model =“ newObject [item.name]”>',这是我所缺少的吗?
乔治·阿南达·埃曼

嗯,很奇怪,刚刚添加了一个在线示例(由于某些原因jsFiddle今天无法在我这边工作)。
pkozlowski.opensource

啊,是的,我习惯于在php中进行思考,并期望将实际的标记更改为该名称,这是可行的。谢谢!
乔治·阿南达·埃曼

2
很棒,正是我想要的。我爱Angular!
2013年

1
它在Angular 2中也很好用。但是多维对象也有解决方案吗?在你的榜样,如果item.name有时应该指出newObject['x'],有时到newObject['x']['y']
马丁·施耐德

23

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

以防万一您像我一样在执行更复杂的任务时绊倒一个简单的案例,这是我想出的将任意表达式动态绑定到ng-model的解决方案:http : //plnkr.co/edit/ccdJTm0zBnqjntEQfAfx?p =预览

方法:我创建了一个指令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的表达式。

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

问候,Justus


3
你是救星。找到这篇文章之前,我几乎绝望了。
Nelo Mitranim

您能更具体点说Brian吗?您尝试了什么,发生了什么?
Justus Wingert 2014年

这是解决方案的竞争宝珠。您使我摆脱了一个非常棘手的问题-谢谢!
Mikebert4

1
ng-change不适用于此功能。如果查看角度源,则ngChange指令将ngModel作为必需指令。快速搜索显示仅ngChange和ngList出现此问题。所有其他指令似乎都将ngModel作为可选控制器。我通过使用dynamic-model指令将ng-model =“ dummyValue”添加到任何元素来解决此问题。由于对动态模型的更改调用$ compile,因此使用ng-model值的ngChange和任何其他指令将正确更新。
EverPresent 2015年

1
当您不需要观看动态模型值的更改时,这是一种更可靠的解决方案-stackoverflow.com/a/32096328/887092
Todd

6

在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


如果我缺少任何内容,请原谅我,但是关于您的小事似乎没有包含动态模型分配。ngModelOptions显然没有任何支持。您能否澄清一下?因为如果这样做的话,它将非常有用……
XML

@XMLilley“ getterSetter:布尔值,它确定是否将绑定到ngModel的函数视为getter / setter。”
克里斯·博尔顿

感谢Rob引起我的注意,我已经更新了答案并链接到您的答案。
Justus Wingert'3

1

这是我支持更深层表达的方法,例如'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。
卡尼特·梅克里希提

0

<!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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.