2012-09-23 115 views
82

我想填充一些动态问题形式(小提琴here):如何在AngularJS中设置动态模型名称?

<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}}"]); 
    }; 
}​ 

一切正常,除了模型实际上是答案[“{{question.Name}}”],而不是评价答案[ “GenderQuestion”]。我怎样才能动态设置模型名称?

回答

112

http://jsfiddle.net/DrQ77/

您可以简单地把JavaScript表达式中ng-model

+1

我发誓,我试过了。非常感谢你。我实际上走了一条不同的路线,只是将模型设置为question.Answer(我会稍微提出一个更新的小提琴),这实际上是一个更直接的答案(要摆脱jQuery的心态),但很高兴知道我的确可以按照我原先计划的未来的方式进行。再次感谢! –

+5

更新的小提琴:http://jsfiddle.net/2AwLM/23/ –

+0

如果这有助于其他人,我有类似的问题,但我的问题是,我使用'ng-pattern =“field.pattern”'时我真正想要的是'pattern =“{{field.pattern}}”'。令人困惑的是角度通常为动态属性提供帮助,但是这次他们写了自己的客户端验证并给出了相同的名称。 – colllin

10

我最终什么事做的是这样的:

在控制器:

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

所以在模板中,我可以使用完全动态的名称,而不是只在一定的硬编码元素(如在你的“答案”情况下):

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

希望这会有所帮助。

3

为使@abourget提供的答案更加完整,以下代码行中的scopeValue [field]的值可能是未定义的。这将导致错误设置子字段时:

解决这个问题的
<textarea ng-model="scopeValue[field][subfield]"></textarea> 

一种方式是通过添加属性NG焦点=“nullSafe(场)”,让你的代码看起来像下面:

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

然后,你在控制器限定nullSafe(场)如下面:

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

这将保证任何值设置为scopeValue [字段] [子场之前scopeValue [字段]未未定义]。注意:您不能使用ng-change =“nullSafe(field)”来实现相同的结果,因为ng-change在ng-model发生改变后发生,如果scopeValue [field]未定义。

27

你可以使用像这样的东西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

救了我的一天:) – WeMakeSoftware

+0

按预期工作。 – C0ZEN

+1

耶!这是我需要的!谢谢! – Snapman

相关问题