Chained selection in ng-repeat

I'm having trouble defining a scope in ng-repeat. I want to create a chained selection, and I want each line in ng-repeat to exist separately in separate areas. Currently, changing the first selection in any of the rows will change the second selection in all rows.

(Real-life example: I have a form where I need to add cars, first select β€œMake”, pull the β€œModels” from the api and show the models in the second choice. Users should be able to add any number of cars.)

HTML:

<div ng-controller="MyCtrl"> <div ng-repeat="row in rows"> <select ng-options="option.value as option.title for option in options1" ng-model="row.select1" ng-change="updateSelect2(row.select1)"></select> <select ng-options="option.value as option.title for option in options2" ng-model="row.select2"></select> </div> <a ng-click="addRow()">Add Row</a> </div> 

JS:

 function MyCtrl($scope) { $scope.rows = [{}]; $scope.options1 = [ {title: 'Option 1', value: '1'}, {title: 'Option 2', value: '2'}, {title: 'Option 3', value: '3'} ]; $scope.options2 = []; $scope.updateSelect2 = function(val) { if (val === '1') { $scope.options2 = [ {title: 'A', value: 'A'}, {title: 'B', value: 'B'} ]; } else if (val === '2') { $scope.options2 = [ {title: 'AA', value: 'AA'}, {title: 'BB', value: 'BB'} ]; } else { $scope.options2 = [ {title: 'AAA', value: 'AAA'}, {title: 'BBB', value: 'BBB'} ]; } }; $scope.addRow = function() { $scope.rows.push({}); }; } 

FIDDLE HERE

+5
source share
2 answers

For each line, options2 should be split.

A simple solution would be to simply save it inside a string object, but you may need a more complex data structure.

Here is an example using your code .

HTML:

 <div ng-repeat="row in rows"> <select ng-options="option.value as option.title for option in options1" ng-model="row.select1" ng-change="updateSelect2(row.select1, $index)"> </select> <select ng-options="option.value as option.title for option in row.options2" ng-model="row.select2"></select> </div> 

JS:

 $scope.updateSelect2 = function(val, index) { if (val === '1') { $scope.rows[index].options2 = [ {title: 'A', value: 'A'}, {title: 'B', value: 'B'} ]; } else if (val === '2') { $scope.rows[index].options2 = [ {title: 'AA', value: 'AA'}, {title: 'BB', value: 'BB'} ]; } else { $scope.rows[index].options2 = [ {title: 'AAA', value: 'AAA'}, {title: 'BBB', value: 'BBB'} ]; } }; 
+3
source

Ok, here is my final decision. I realized that I can access the ng-repeat scope from the controller by passing the repeat element as a function parameter to ng-change:

HTML:

 <div ng-controller="MyCtrl"> <div ng-repeat="row in rows"> <select ng-options="option.value as option.title for option in select1options" ng-model="row.select1" ng-change="updateSelect2(row.select1, row)"></select> <select ng-options="option.value as option.title for option in row.options" ng-model="row.select2"></select> </div> <a ng-click="addRow()">Add Row</a> </div> 

JS:

 function MyCtrl($scope) { $scope.rows = [{options:[]}]; $scope.select1Options = [ {title: 'Option 1', value: '1'}, {title: 'Option 2', value: '2'}, {title: 'Option 3', value: '3'} ]; $scope.updateSelect2 = function(val, scope) { if (val === '1') { scope.options = [ //<-- this scope is the ng-repeat item scope, from the function parameter {title: 'A', value: 'A'}, {title: 'B', value: 'B'} ]; } else if (val === '2') { scope.options = [ {title: 'AA', value: 'AA'}, {title: 'BB', value: 'BB'} ]; } else { scope.options = [ {title: 'AAA', value: 'AAA'}, {title: 'BBB', value: 'BBB'} ]; } }; $scope.addRow = function() { $scope.rows.push({options:[]}); }; } 

Note1: In the $scope.rows I had to first add the "options" array to each of the objects.

$scope.updateSelect2 : in $scope.updateSelect2 the scope parameter refers to the scope of ng-repeat (in this case row ), not $scope !

FIDDLE HERE

+1
source

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


All Articles