Dynamically assign ng model

I am trying to create a set of checkboxes from an array of objects. I want the checkboxes to dynamically map their ng model to the property of the new object that will be sent to the array.

What I had in mind is something like

<li ng-repeat="item in items"> <label>{{item.name}}</label> <input type="checkbox" ng-model="newObject.{{item.name}}"> </li> 

This does not work, as seen on this JSFiddle:

http://jsfiddle.net/GreenGeorge/NKjXB/2/

Does anyone help?

+76
javascript angularjs
Jan 06 '13 at 15:30
source share
5 answers

This will give you the desired results:

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

Here is the work plan: http://plnkr.co/edit/ALHQtkjiUDzZVtTfLIOR?p=preview

+137
Jan 6 '13 at 15:46
source share

EDIT As correctly noted in the comments, using this with ng-change requires a preliminary preview of the "dummy" ng. However, it should be noted that, apparently, with 1.3, the required parameters were provided by the framework. Please check out the https://stackoverflow.com/a/166338/ below! / EDIT

Just in case, when you are like me, tripping over a simple case, having a more difficult task, this is the solution I came up with for dynamically linking arbitrary expressions to ng-model: http://plnkr.co/edit/ccdJTm0zBnqjntEQfAfx?p= preview

Method: I created a dynamicModel directive that takes a standard angular expression, evaluates it, and associates the result with the scope using ng-model and $ 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); }); } }; }]); 

The use is simply a dynamic model = "angular expression", where the expression of the angular expression leads to a string that is used as the expression for the ng model.

I hope this saves someone the headache of having to come up with this solution.

Regards, Justus

+23
Jul 02 '14 at 8:00
source share

With Angular 1.3, you can use the ng-model-options directive to dynamically assign a model or bind to an expression.

Here is plunkr: 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 }"> 

More information about ngModelOptions here: https://docs.angularjs.org/api/ng/directive/ngModelOptions

+6
Feb 06 '15 at 12:09
source share

This is my approach to supporting deeper expression, for example. 'Model.level1.level2.value'

 <input class="form-control" ng-model="Utility.safePath(model, item.modelPath).value"> 

where item.modelPath = 'level1.level2' and Utility (model, 'level1.level2') is a utility function that returns model.level1.level2

+1
Oct 08 '15 at 8:33
source share

 <!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> 
0
Jul 13 '17 at 18:24
source share



All Articles