簡體   English   中英

級聯父子項從動態JSON數據中選擇框

[英]Cascading parent child select boxes from dynamic JSON data

我已經從JSON數據動態創建了一些鏈式選擇框,我將從服務器收到這些數據。 鏈接/級聯的工作方式是每個選擇框都是具有以下屬性的命名對象:

  1. 父屬性:作為此選擇框對象的父對象的對象的名稱。
  2. 選項:選項對象的數組,其中每個對象包含:(a)選項值(b)父選項值 - 用於映射當前值的父選擇框值。 (c)選項ID。

  3. 選定選項:具有兩個屬性的對象:(a)當前選定的值(b)當前所選值的ID。

我在“選項”標簽中使用ng-repeat創建選擇框,或者在“select”標簽中使用ng-option,然后我使用自定義過濾器,我通過匹配父選項值來過濾檢索到的選項(2) (2> b)選項值(2> a)與其父對象的“當前選擇值”(3> a)。 基本上使用自定義過濾器從子選項值到選定父值進行多對一映射。

在此輸入圖像描述

我能夠正確映射父子選擇框,但問題是當我更改父選擇框值時,其子對象的“選定選項值”不會更新( 子選擇的項目不會抓取篩選列表中的第一項,導致孫子下拉不更新。[1]

有沒有辦法,如果父值更改,子選擇框(以及后續的子/孫)使用第一個選項值而不是當前空白值初始化?

這是工作的plunker。 (ng-repeat實施)。 真的很感激任何幫助。

這是另一個帶有ng-options實現的plunker

HTML(ng-repeat):

<div ng-repeat="selection in vm.selectionData">
    <div ng-repeat="(key, attribute) in selection.attributes">
      <span>{{key}}</span>
      <select class="form-control" ng-model="attribute.selectedOption.name">
        <option ng-repeat="option in attribute.options | optionFilter : selection.attributes[attribute.parentAttr]">{{option.name}}</option>
      </select>
    </div>
</div>

HTML(ng-options):

<div ng-repeat="selection in vm.selectionData">
    <div ng-repeat="(key, attribute) in selection.attributes">
      <span>{{key}}</span>
      <select ng-model="attribute.selectedOption" ng-options="attribute.name for attribute in (attribute.options | optionFilter : selection.attributes[attribute.parentAttr]) track by attribute.id">
      </select>
    </div>        
</div>

JS:

myApp.filter('optionFilter', function() {
  return function(items, parent) {
    var result = [];
    if (parent) {
      for (var i = 0; i < items.length; i++) {
        console.log(items[0].parent, parent.selectedOption.name);
        if (items[i].parent === parent.selectedOption.name) {
          result.push(items[i]);
        }
      }
      return result;
    } else {
      return items;
    }
  }
});

myApp.controller("MyCtrl", function($scope) {

  this.selectionData = [{
    selectionType: "Geography",
    attributes: {
      country: {
        parentAttr: "none",
        options: [{
          name: "India",
          parent: "None",
          id: 1
        }, {
          name: "Bangladesh",
          parent: "None",
          id: 2
        }, {
          name: "Afganistan",
          parent: "None",
          id: 3
        }],
        selectedOption: {
          name: "India",
          id: 1
        }
      },
      state: {
        parentAttr: "country",
        options: [{
          name: "Rajasthan",
          parent: "India",
          id: 1
        }, {
          name: "Haryana",
          parent: "India",
          id: 2
        }, {
          name: "Dhaka",
          parent: "Bangladesh",
          id: 3
        }, {
          name: "Kabul",
          parent: "Afganistan",
          id: 4
        }],
        selectedOption: {
          name: "Rajasthan",
          id: 1
        }
      },
      city: {
        parentAttr: "state",
        options: [{
          name: "Kota",
          parent: "Rajasthan",
          id: 1
        }, {
          name: "Sirsa",
          parent: "Haryana",
          id: 2
        }, {
          name: "Alwar",
          parent: "Rajasthan",
          id: 3
        }, {
          name: "Gurgaon",
          parent: "Haryana",
          id: 4
        }, {
          name: "Kabul",
          parent: "Kabul",
          id: 5
        },{
          name: "Dhaka",
          parent: "Dhaka",
          id: 6
        }
        ],
        selectedOption: {
          name: "Kota",
          id: 1
        }
      }
    },
  }];

});

參考文獻:

經過一段時間的努力,我想出了一個解決方案(雖然不確定它是否符合最佳實踐)。 在我的自定義過濾器中,它根據父對象的選定選項值返回已過濾的選項,我另外發送當前的選擇框對象。 然后,

  1. 過濾器首先檢查父對象是否存在,否則返回所有選項。
  2. 如果父存在,則它循環遍歷當前選擇框對象的所有可用選項。
  3. 如果當前選擇框選項的父值與父對象的選定選項值匹配,則僅當父對象的選定選項不為空時 ,它才會推送結果數組中的已過濾選項值(當祖父項值更改時,父對象的選定選項可以為空和父級不會抓取結果篩選的選項,導致父選擇框中的空白第一個選項)。 這將暫時導致當前選擇框完全為空,因為父對象的selected選項為null。
  4. 然后,它檢查當前選擇框對象的選定選項是否為空。 如果是這樣,它將結果數組的第一個元素(對象)分配給選定的選項對象,並返回結果數組。 由於過濾器將針對所有選擇框(祖父,父和子)運行,因此它會將父過濾數組中的第一個元素設置為父對象的選定選項。 現在,當父對象的selected選項不再為null時,當前選擇框將顯示已篩選的選項(來自結果數組),結果數組的第一個元素將分配給當前選擇框的選定選項。

在這里工作演示。 請分享是否有更好的解決方案。 以下是自定義過濾器:

myApp.filter('optionFilter', function() {
  return function(items, parent, self) {
    var result = [];
    if (parent) {
      for (var i = 0; i < items.length; i++) {
        if (parent.selectedOption !== null && items[i].parentValue === parent.selectedOption.value) {
          result.push(items[i]);
        }
      }
      if (self.selectedOption === null) {
        self.selectedOption = result[0];
      }
      return result;
    } else {
      return items;
    }
  }
});

HTML:

<div ng-repeat="(key, item) in data">
    <span>{{key}}</span>
    <select ng-model="item.selectedOption" ng-options="option.value for option in (item.availableOptions | optionFilter : data[item.parent] : item) track by option.id">
    </select>
</div>

數據:

this.data = {
  Country: {
    parent: "None",
    availableOptions: [{
      value: "United States",
      parentValue: "None",
      id: 1
    }, {
      value: "China",
      parentValue: "None",
      id: 2
    }, {
      value: "India",
      parentValue: "None",
      id: 3
    }],
    selectedOption: {
      value: "United States",
      parentValue: "None",
      id: 1
    }
  },
  State: {
    parent: "Country",
    availableOptions: [{
      value: "California",
      parentValue: "United States",
      id: 1
    }, {
      value: "Shanghai",
      parentValue: "China",
      id: 2
    }, {
      value: "Delhi",
      parentValue: "India",
      id: 3
    }],
    selectedOption: {
      value: "California",
      parentValue: "United States",
      id: 1
    }
  },
  City: {
    parent: "State",
    availableOptions: [{
      value: "Greenfield",
      parentValue: "California",
      id: 1
    }, {
      value: "Shanghai",
      parentValue: "Shanghai",
      id: 2
    }, {
      value: "New Delhi",
      parentValue: "Delhi",
      id: 3
    }],
    selectedOption: {
      value: "Greenfield",
      parentValue: "California",
      id: 1
    }
  }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM