How to set dynamic model name in AngularJS?

I want to fill out a form with dynamic questions (fiddle 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}}"]); }; }​ 

Everything works, except that the model literally answers ["{{question.Name}}"], and not to the rated answers ["GenderQuestion"]. How to set the dynamic name of this model?

+88
angularjs
Sep 23
source share
4 answers

http://jsfiddle.net/DrQ77/

You can just put the javascript expression in ng-model .

+119
Sep 23 '12 at 21:55
source share

You can use something like this scopeValue[field] , but if your field is in another object, you will need a different solution.

To solve all situations, you can use this directive:

 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 example:

 <input dynamic-model="'scopeValue.' + field" type="text"> 
+31
Aug 19 '15 at 13:03
source share

What I finished looks something like this:

In the controller:

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

therefore, in the templates I could use fully dynamic names, and not just under a certain hard-coded element (for example, in your case, β€œAnswers”):

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

Hope this helps.

+12
Apr 12 '13 at 18:43
source share

To make the answer provided by @abourget more complete, the value of the scopeValue [field] field in the next line of code can be undefined. This will result in an error when setting up the subfield:

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

One way to solve this problem is to add the ng-focus = "nullSafe (field)" attribute, so your code will look like this:

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

Then you define a nullSafe (field) in the controller, as shown below:

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

This ensures that scopeValue [field] is not undefined before setting any value to scopeValue [field] [subfield].

Note: you cannot use ng-change = "nullSafe (field)" to achieve the same result, because ng-change occurs after changing the ng model, which will cause an error if scopeValue [field] is undefined.

+3
Jun 28 '14 at 23:40
source share



All Articles