2012-09-23 51 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

相關問題