tr内的角度ng-repeat打破了级联下拉列表

时间:2016-12-01 13:09:59

标签: javascript jquery html angularjs

我使用的是角1.4.8版本。 我使用字符串数组,使用ng-repeat迭代表,三个使用级联下拉列表。 问题是: 在第0行:我填充选择,当我进入row1时,我做出不同的选择,在row0上预先选择的选项会被更改。

have checked on [$index] property too

Js小提琴链接

https://jsfiddle.net/sprakashg/vct4wcab/

2 个答案:

答案 0 :(得分:0)

问题是您保留用户可以在$scope变量中选择的可能选项。这个$scope变量是针对表格中的每一行共享的,因此如果您更改例如$scope.subTpe$scope.pType,则会进行全局更改。现在,因为Angular具有双向数据绑定,如果它看到这个$scope变量发生了变化,它将重新渲染依赖于它的所有项目,即其他行中的所有其他下拉列表。

例如:

<select ng-options = "k as v for (k,v) in productCategory" 
        ng-change  = "productSubCategory($index, item.check1)" 
        ng-model   = "item.check1">

变量productCategory指的是$scope.productCategory,因此指的是全局$scopeng-change会触发$scope的更改,以便更改所有下拉框。相反的值具有正确的绑定,它的绑定是指项目和项目在每一行都不同。

每次更改下拉菜单时,例如:

$scope.pType = [ "Skirts" ]

您正在影响整个$scope,从而影响所有下拉列表。

要修复,您必须跟踪每行和每列中的每个列表。因此,您必须为每个行和列保留必须显示的下拉项的数据结构。所以你需要的是这样的东西:

item.possibleProductCategoriesToChooseFrom
item.possibleSubcategoriesToChooseFrom
item.possibleProductTypesToChooseFrom

这样你的ng-options就会发生这样的变化:

<select ng-options = "k as v for (k,v) in item.possibleProductCategoriesToChooseFrom" 
        ng-change  = "productSubCategory($index, item)" 
        ng-model   = "item.check1">

请注意,您必须将完整项目传递给更改侦听器,以便能够在项目上设置可供选择的项目。

在您的更改侦听器中,您希望设置用户可以选择的可能值的正确列表,例如:

item.possibleProductTypesToChooseFrom = [ "Skirts" ];

它有点复杂,因为页面中有很多动态构建,但没有其他方法可以执行此操作,因为您必须保持页面中所有下拉组件的状态。

答案 1 :(得分:0)

您可以实现隔离指令概念来实现相同的目的。实际上,您的场景非常适合隔离的指令实现。另外建议将所有数据源和逻辑保留在服务中而不是控制器中。我创建了示例实现来演示相同的内容。

Plunkar - https://plnkr.co/edit/92hxBy2zGGsQLAsf3ZWE?p=preview

希望这会有所帮助!

指令 -

app.directive("product", function(productService) {
  return {
    templateUrl: "loadTableData.html",
    replace: true,
    scope: {
      product: '='
    },
    link: function($scope) {
      $scope.productCategory = productService.getProductCategory();
      $scope.productSubCategory = function(index, field) {
        $scope.subType = productService.getProductSubCategory($scope.productCategory[field]);
      };
      $scope.productType = function(index, parent, field) {
        $scope.pType = productService.getProductType($scope.productCategory[parent], $scope.subType[field]);
      }
    }
  }
});

loadTableData.html

<tr>
  <td>{{product.sku}}</td>
  <td><img ng-src='{{product.image}}'></td>
  <td>
    <select ng-options='k as v for (k,v) in productCategory' ng-change='productSubCategory($index, item.check1)' ng-model='item.check1'>
      <option value='' disabled>Select Product Category</option>
    </select>
  </td>
  <td>
    <select ng-model='item.check2' ng-options='a as b for (a,b) in subType' ng-change='productType($index, item.check1, item.check2)'>
      <option value='' disabled>Select Product Sub-Category</option>
    </select>
  </td>
  <td>
    <select ng-model='item.check3' ng-options='c as d for (c,d) in pType'>
      <option value='' disabled>Select Product Type</option>
    </select>
  </td>
</tr>

用法:

<tbody>
        <tr data-ng-repeat="item in products" class="text-center" product="item">
</tbody>

产品服务:

app.service('productService', function() {
  var productCategory = [
    'Bags',
    'Shoes',
    'Western Wear',
    'Ethnic Wear',
    'Accessories',
    'Home & Decor',
  ];

  this.getProducts = function() {
    return [{
      "sku": "FSLPEW0086",
      "image": "http://imgprd.styletagassets.com/FSLPEW0086_1.jpg?resize=110px:139px"
    }, {
      "sku": "FSLPEW0087",
      "image": "http://imgprd.styletagassets.com/FTTPEW0085_1.jpg?resize=110px:139px"
    }, {
      "sku": "FSLPEW0089",
      "image": "http://imgprd.styletagassets.com/FSLPEW0084_1.jpg?resize=110px:139px"
    }];
  }

  this.getProductCategory = function() {
    return productCategory;
  }

  this.getProductSubCategory = function(productCategoryName) {
    console.log(productCategoryName)
    var subType = [];
    if (productCategoryName == 'Ethnic Wear') {
      subType = [
        "Kurtas",
        "Kurtis",
        "Anarkalis",
        "Suits",
        "Churidars",
        "Salwars",
        "Palazzos",
        "Skirts",
        "Sarees"
      ]
    } else if (productCategoryName == 'Skirts') {

    }
    return subType;
  }

  this.getProductType = function(productCategoryName, subCategoryName) {
    console.log(productCategoryName)
    console.log(subCategoryName)
    var pType = [];
    if ((productCategoryName == 'Ethnic Wear') && (subCategoryName == 'Sarees')) {
      pType = [
        "Traditional Sarees",
        "Occassionwear Sarees",
        "Bollywood Sarees",
        "Bandhani & Bandhej Sarees",
        "Lehenga Sarees",
        "Dailywear Sarees",
        "Printed Sarees"
      ];
    } else if ((productCategoryName == 'Ethnic Wear') && (subCategoryName == 'Skirts')) {
      pType = [
        "Skirts"
      ]
    } else if ((productCategoryName == 'Ethnic Wear') && (subCategoryName == 'Palazzos')) {
      pType = [
        "Palazzos",
        "Culottes"
      ]
    } else if ((productCategoryName == 'Ethnic Wear') && (subCategoryName == 'Salwars')) {
      pType = [
        "Salwars",
        "Patiala",
        "Patiala & Dupatta Sets",
        "Harem Pants",
        "Jodhpuris",
        "Dhoti Salwars"
      ]
    }
    return pType;
  }
});