如何在AngularJS中设置动态模型名称?

时间:2012-09-23 15:32:11

标签: angularjs

我想用一些动态问题填充表单(小提琴here):

<div ng-app ng-controller="QuestionController">
    <ul ng-repeat="question in Questions">
        <li>
            <div>{{question.Text}}</div>
            <select ng-model="Answers['{{question.Name}}']" ng-options="option for option in question.Options">
            </select>
        </li>
    </ul>

    <a ng-click="ShowAnswers()">Submit</a>
</div>
​
function QuestionController($scope) {
    $scope.Answers = {};

    $scope.Questions = [
    {
        "Text": "Gender?",
        "Name": "GenderQuestion",
        "Options": ["Male", "Female"]},
    {
        "Text": "Favorite color?",
        "Name": "ColorQuestion",
        "Options": ["Red", "Blue", "Green"]}
    ];

    $scope.ShowAnswers = function()
    {
        alert($scope.Answers["GenderQuestion"]);
        alert($scope.Answers["{{question.Name}}"]);
    };
}​

一切正常,除了模型字面上是Answers [“{{question.Name}}”],而不是评估的答案[“GenderQuestion”]。如何动态设置该型号名称?

5 个答案:

答案 0 :(得分:116)

http://jsfiddle.net/DrQ77/

您可以简单地将javascript表达式放在ng-model

答案 1 :(得分:30)

您可以使用此类scopeValue[field]之类的内容,但如果您的字段位于其他对象中,则需要其他解决方案。

要解决所有情况,您可以使用此指令:

this.app.directive('dynamicModel', ['$compile', '$parse', function ($compile, $parse) {
    return {
        restrict: 'A',
        terminal: true,
        priority: 100000,
        link: function (scope, elem) {
            var name = $parse(elem.attr('dynamic-model'))(scope);
            elem.removeAttr('dynamic-model');
            elem.attr('ng-model', name);
            $compile(elem)(scope);
        }
    };
}]);

Html示例:

<input dynamic-model="'scopeValue.' + field" type="text">

答案 2 :(得分:12)

我最终做的是这样的:

在控制器中:

link: function($scope, $element, $attr) {
  $scope.scope = $scope;  // or $scope.$parent, as needed
  $scope.field = $attr.field = '_suffix';
  $scope.subfield = $attr.sub_node;
  ...

因此在模板中我可以使用完全动态的名称,而不仅仅是在某个硬编码元素下(例如在你的&#34; Answers&#34;案例中):

<textarea ng-model="scope[field][subfield]"></textarea>

希望这有帮助。

答案 3 :(得分:3)

为了使@abourget提供的答案更加完整,下一行代码中的scopeValue [field]的值可能是未定义的。设置子字段时会出错:

<textarea ng-model="scopeValue[field][subfield]"></textarea>

解决此问题的一种方法是添加属性ng-focus =&#34; nullSafe(field)&#34;,因此您的代码如下所示:

<textarea ng-focus="nullSafe(field)" ng-model="scopeValue[field][subfield]"></textarea>

然后在控制器中定义nullSafe(字段),如下所示:

$scope.nullSafe = function ( field ) {
  if ( !$scope.scopeValue[field] ) {
    $scope.scopeValue[field] = {};
  }
};

这可以保证在将任何值设置为scopeValue [field] [subfield]之前未定义scopeValue [field]。

注意:您不能使用ng-change =&#34; nullSafe(field)&#34;为了达到相同的结果,因为ng-change在ng-model更改后发生,如果scopeValue [field]未定义,则会引发错误。

答案 4 :(得分:0)

或者您可以使用

<select [(ngModel)]="Answers[''+question.Name+'']" ng-options="option for option in question.Options">
        </select>