How to create closure for getter-setter model in angular?

I have some data that I process when using angular ng-repeat. I want to allow the user to select items in the field of view by checking the checkboxes in front of each item. The simplest is to add the "selected" property to each element of the model. However, I would prefer to more accurately separate the problems and not pollute the data model with the state of the user interface. I also send the data back to the server, and I would rather not sanitize it before doing this. Therefore, it is best for IMO to have a separate model of choice. Basically I am trying to do something like this:

Controller:

$scope.data = [ {'name': 'a', 'value': '1'}, {'name': 'b', 'value': '2'}, {'name': 'c', 'value': '3'} ]; $scope.selection = {'a': false, 'b': false, 'c': false}; $scope.createSelectionGetterSetter = function(name) { return function(newValue) { if (angular.isDefined(newValue)) { selection[name] = newValue; } return selection[name]; } }; 

View:

 <div ng-repeat='row in data'> <input type='checkbox' ng-model='createSelectionGetterSetter(row.name)' ng-model-options='{ getterSetter: true }' /> <input type='text' ng-model='row.value' /> </div> 

The idea here is to createSelectionGetterSetter to create a closure that createSelectionGetterSetter selection state to the correct element in the selection model. Of course, this does not work, because angular expects the actual getter / setter function in the ng model.

How to create such locks and pass them to angular view as getters / setters?

+2
source share
1 answer

You can easily execute with $watchCollection to define the selection variable:

 $scope.$watchCollection('data', function(newval) { $scope.selection = {}; if( newval ) { angular.forEach(newval, function(val) { $scope.selection[val.name] = false; }); } }); 

And using it like:

 <input type='checkbox' ng-model='selection[row.name]' /> 

See the script: http://jsfiddle.net/54u0vztr/

Catch: To set the initial value for selection , some configuration is required if you want the values ​​to be saved when the data changes. I believe that they are more or less trivial to implement.


If you want to use the getterSetter function, just add $scope. selection[name] to your code!

Fiddle: http://jsfiddle.net/qc5qtg5q/

Catches:

  • Using this method, the access function is constantly recreated. This can affect performance (both speed and memory usage), at least on a real page. To visualize it, add console.log('Creating accessor') at the beginning of the createSelectionGetterSetter function.

  • You will need additional processing for the case when the data list is changed, although now you can easily specify the initial values ​​for selection .

+1
source

Source: https://habr.com/ru/post/1211342/


All Articles