0

我正在尝试根据我的需要自定义这个 Angular Material 示例代码(https://material.angularjs.org/latest/api/directive/mdSelect)。

我有三组选择选项。如果在组中选择了一个选项,则应取消选择其他组中的所有选项(但将其他选项保留在自己的组中)。

在我的代码中,我设法使逻辑正常工作(正如您将从底部的 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();
            });



});
4

1 回答 1

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 inline 的状态与更改事件后 ng-model 的指定状态。而 ng-click 对此并不可靠。

  2. 像这样在 html 中编写 ng-change 函数: ng-change="clickOn(mustCatSelected, '{{mustCatSelected}}')" 其中 mustCatSelected 是 ng-model 并且 '{{mustCatSelected}}' 是 ng 的内联状态-更改事件之前的模型。

现在我们有一个多重 md-select 逻辑处理选项/选项组的选择。

于 2017-09-30T14:05:05.607 回答