在 ng-repeat 中链接 select

chained select within ng-repeat

我无法确定 ng-repeat 中的范围。我想创建链式 selects,并且我想让 ng-repeat 中的每一行分别存在于不同的范围内。当前更改任何行中的第一个 select 将更改所有行中的第二个 select。

(现实生活中的例子:我有一个表格,我必须添加汽车,首先选择一个 'Make',从 api 中拉出它的 'Models',然后在第二个 select。用户必须能够添加任意数量的汽车。)

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

您需要为每一行分隔 options2 部分。

一个简单的解决方案是将它保存在行对象中,但您可能需要更复杂的数据结构。

这是一个简单的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'}
    ];
  }
};

好的,这是我的最终解决方案。我意识到我可以从控制器访问 ng-repeat 范围,方法是将重复项作为 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's 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:[]});
  };
}

注意 1:在 $scope.rows 数组中,我必须为每个对象预先添加一个 'options' 数组。

注2:在$scope.updateSelect2中,scope参数指的是ng-repeat项目的范围(在本例中为row),而不是$scope

FIDDLE HERE