2017-08-15 59 views
0

我正試圖根據自己的需要定製此角度材質示例代碼(https://material.angularjs.org/latest/api/directive/mdSelect)。我有三組選擇選項。如果在一個組中選擇了一個選項,它應該取消選擇其他組中的所有選項(但保留自己組中的其他選項)。角度材質md-select和trackBy允許選擇

在我的代碼中,我設法使邏輯正常工作(您將從底部的console.log輸出中看到),但實際的選擇選項不會與用戶輸入交互。

我的jsfiddle:https://jsfiddle.net/e2LLLxnb/8/

我的JS代碼:

var myModule = angular.module('BlankApp', ['ngMaterial']); 
myModule.controller("FilterCtrl", function($scope, $element) { 

    $scope.categories = ["Any", "Target Category", "Option 1", "Option 2", "Option 3", "Option 4"]; 

      $scope.mustCatSelected; 

      $scope.categoryObj = {}; 
      // build the list of options with values and groups - create equivalent of $scope.data for <md-option ng-repeat="item in categoryObj.data.items"> 
      var finGroup = []; 
      $scope.categories.forEach(function(value,key){ 
       if(key>1){ 
        finGroup.push(key); 
       }; 

      }); 

      $scope.categoryObj.data = {items: [], groups: [{ 
                  group: [0] 
                  }, { 
                  group: [1] 
                  }, { 
                  group: finGroup 
                  }]}; 

      $scope.categories.forEach(function(value,key){ 

       $scope.categoryObj.data.items.push({name: value, 
                value: false, 
                id: (key + 1)}); 

      }); 


      $scope.clickOn = function(item, index) { 

      if(item.value == false){item.value = item.name;} 
      else {item.value = false;} 

       if (item.value === false) { 

       } else { 

       var thisGroup = []; 
       angular.forEach($scope.categoryObj.data.groups, function(value, key) { 

        if (value.group.indexOf(index) !== -1) { 
        thisGroup = value.group; 
        } 
       }); 



       angular.forEach($scope.categoryObj.data.items, function(value, key) { 

        if (thisGroup.indexOf(key) !== -1) { 
        return; 
        } else { 
        value.value = false; 
        } 
       }); 

       $scope.mustCatSelected = $scope.categoryObj.data.items.filter(function(e){ 


          return e.value != false; 

       });    
       console.log($scope.mustCatSelected);     
       console.log($scope.categoryObj.data.items); 

       } 


      }   


      //search-term header 
      $scope.searchTerm; 
      $scope.clearSearchTerm = function() { 
       $scope.searchTerm = ''; 
      }; 
       // The md-select directive eats keydown events for some quick select 
       // logic. Since we have a search input here, we don't need that logic. 
      $element.find('input').on('keydown', function(ev) { 
        ev.stopPropagation(); 
      }); 



}); 

回答

1

解決了(終於!):https://jsfiddle.net/hqck87t1/4/

var myModule = angular.module('BlankApp', ['ngMaterial']); 
    myModule.controller("FilterCtrl", function($scope, $element) { 

       $scope.categories = ["Any", "None", "Option 1", "Option 2", "Option 3", "Option 4"]; 

       $scope.mustCatSelected = []; 

       $scope.categoryObj = {}; 
       $scope.categoryObj.items = []; 
       $scope.categories.forEach(function(value,key){ 
        var grp; 
        if (key < 2){grp = key;} 
        if (key >= 2){grp = 2;} 
        $scope.categoryObj.items.push({ 
                 name: value, 
                 id: (key + 1), 
                 group: grp});      
       });   
       //set default 
       $scope.mustCatSelected.push($scope.categoryObj.items[0]); 






       $scope.clickOn = clickOn; 
       function clickOn(newValue, oldValue, type) { 

        //console.log($scope.categoryObj.items); 
        //console.log(oldValue); 
        if(oldValue.length == 0) { 
         return false; 
        } 

        //create arrays of new and old option ids 
        oldValue = JSON.parse(oldValue); 
        var newIds = []; 
        var oldIds = []; 

        newValue.forEach(function(value,key){ 

         newIds.push(value.id); 

        }); 

        oldValue.forEach(function(value,key){ 

         oldIds.push(value.id); 

        }); 

        //define and set the clicked value 
        var clickedValue; 
        newIds.forEach(function(value, key){ 

         if(oldIds.indexOf(value) == -1) { 
          clickedValue = value; 
         } 

        }); 

        var clickedGroup; 
        newValue.forEach(function(value,key){ 

         if(value.id == clickedValue){ 

          clickedGroup = value.group; 

         } 

        }); 

        //console.log([clickedValue, clickedGroup]);  
        //console.log([newIds, oldIds, clickedValue]); 
        if(type == 'mustCat'){ 
         $scope.mustCatSelected = $scope.mustCatSelected.filter(function(e){ 

           return e.group == clickedGroup; 

         }); 
        } 

       } 


       //search term above select 
       $scope.searchTerm; 
       $scope.clearSearchTerm = function() { 
        $scope.searchTerm = ''; 
       }; 
        // The md-select directive eats keydown events for some quick select 
        // logic. Since we have a search input here, we don't need that logic. 
       $element.find('input').on('keydown', function(ev) { 
         ev.stopPropagation(); 
       }); 



    }); 

有關鍵的解決辦法在於兩點:

  1. 使用ng-change代替ng-click。前者用於區分ng-model內聯狀態與change-事件後ng-model的指定狀態。而ng-click對此不可靠。

  2. 寫在這樣的HTML的NG-改變功能: NG-變化= 「clickOn(mustCatSelected, '{{mustCatSelected}}')」 其中mustCatSelected是NG-模型和「{{mustCatSelected} }'更改事件之前的ng-model的內聯狀態。

現在我們有一個多選的md-select,其邏輯處理選項/選項組的選擇。