选择使用ngOptions选择另一个数组的过滤器

时间:2015-12-16 16:52:11

标签: javascript arrays angularjs ng-options angularjs-ng-options

编辑:Plunker显示问题:http://plnkr.co/edit/R5vNvejX3ncdqSzZst17?p=preview

使用AngularJS,我有一个包含任务的主数组,如:

tasks.myTasks = [
    {task: "Task 1", done: "Y"}
    {task: "Task 2", done: "N"}
];

我想在屏幕上设置一个有三个选项的选择:

  1. 显示所有任务。
  2. 仅显示已完成的任务。
  3. 仅显示撤消的任务。
  4. 我所做的是设置一个带有选项的数组,以及一个在我重复myTasks时设置为过滤器的变量:

    tasks.filteringOptions = [
        "all": '',
        "only_done": {done: "Y"},
        "only_undone": {done: "N"}
    ];
    tasks.filter = tasks.filteringOptions[0];
    

    在我的HTML上,我按照以下方式执行ng-repeat:

    <select ng-model="tasksCtrl.filter" ng-options="value as key for (key, value) in tasksCtrl.filteringOptions">
    </select>
    
    <div ng-repeat="task in tasksCtrl.myTasks | filter:tasksCtrl.filter">
       ...
    </div>
    

    唯一的问题是上面的代码不起作用,当选择数组的第一项(all: '')时它工作正常,但是当我单击选择并将其更改为其中一个时选项,它不起作用。

    为了测试它,我在HTML代码中评论了我的select并创建了一个输入:

    <input ng-model="tasksCtrl.filter.done" type="text">
    

    这种方法运行正常,我在输入中键入“Y”或“N”,并按预期过滤myTasks。所以我认为选择错误地设置了tasksCtrl.filter,所以我在tasksCtrl.filterselect的顶部放置了一个值为input的div,并对它们进行了测试我会得到什么。

    他们都在我的HTML上返回了完全相同的结果:

    {"done": "Y"}
    

    我也尝试使用ng-repeat构建我的select,但我在网上看到它不接受value上的对象,所以我使用的是ng-options。

    我也注意到了这一点:如果我尝试将filter变量设置为{"done": "Y"},当我使用输入时它工作正常,第一个结果已经过滤,但如果我放置选择其中的ng-options,过滤器不再起作用。

    最后一个问题是:我是否需要处理我的对象值以将其传递给ng-options?如果没有,输入和选择如何在变量tasksCtrl.filter内显示相同的结果,但选择不会按预期工作?

2 个答案:

答案 0 :(得分:2)

&#13;
&#13;
// Code goes here

var app =angular.module('myApp', []);
app.filter('custfilter', function(){
  
   
   return function(input, obj)
   {
     var val = JSON.stringify(obj);
     var inputval = JSON.stringify(input);
     //here use jquery to filter and return the data it will work
     return input;   
   }
})



  app.controller('myController1', function(){
    var vm = this;
    
    vm.myTasks = [
      {'task': 'Task 1', 'done': 'Y'}, 
      {'task': 'Task 2', 'done': 'Y'}, 
      {'task': 'Task 3', 'done': 'Y'}, 
      {'task': 'Task 4', 'done': 'N'}, 
      {'task': 'Task 4', 'done': 'N'} 
    ];
    
    
    vm.filteringOptions = {
      'all': '',
      'only_done': {done: 'Y'},
      'only_undone': {done: 'N'}
    };
    
    vm.filter = vm.filteringOptions['only_done'];
  
  })
  app.controller('myController2', function(){
    var vm = this;
    
    vm.myTasks = [
      {'task': 'Task 1', 'done': 'Y'}, 
      {'task': 'Task 2', 'done': 'Y'}, 
      {'task': 'Task 3', 'done': 'Y'}, 
      {'task': 'Task 4', 'done': 'N'}, 
      {'task': 'Task 4', 'done': 'N'} 
    ];
    
    
    vm.filteringOptions = {
      'all': {done: ''},
      'only_done': {done: 'Y'},
      'only_undone':{done: 'N'},
    };
    
    vm.filter = vm.filteringOptions['only_done'];
  
  })
;
&#13;
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>

    <script src="script.js"></script>


  <body ng-app="myApp">
    <div ng-controller="myController1 as myCtrl1">
      <h1>myController1: input (working)</h1>
      Here I am using a input below to filter myArray.<br/><br/>
      myTasks (filtered):
      <ul>
        <li ng-repeat="task in myCtrl1.myTasks | filter:myCtrl1.filter">Task: {{ task.task }} - Done? {{ task.done }} </li>  
      </ul>
      "filter.done" here, type here to see it changing correctly: <input type="text" ng-model="myCtrl1.filter">
      
    </div>
    <br/>
    <br/>
    <br/>
    <div ng-controller="myController2 as myCtrl2">
      <h1>myController2: select (not working)</h1>
      Here I have copied and pasted the same controller, identically stablished. But as you can see, it is showing nothing. <br/><br/>
      myTasks (won't show, choose "all" in the select below):
      <ul>
        <li ng-repeat="task in myCtrl2.myTasks | custfilter:myCtrl2.filter">Task: {{ task.task }} - Done? {{ task.done }} </li>  
      </ul>
      If you choose "all" it works, otherwise it won't work: <select ng-model="myCtrl2.filter" class="pull-right" ng-options="value as key for (key, value) in myCtrl2.filteringOptions"></select>
      
    </div>    
  </body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

// Code goes here

var app =angular.module('pof', []);
 


  app.controller('myController1', function(){
    var vm = this;
    
    vm.myTasks = [
      {'task': 'Task 1', 'done': 'Y'}, 
      {'task': 'Task 2', 'done': 'Y'}, 
      {'task': 'Task 3', 'done': 'Y'}, 
      {'task': 'Task 4', 'done': 'N'}, 
      {'task': 'Task 4', 'done': 'N'} 
    ];
    
    
    vm.filteringOptions = {
      'all': '',
      'only_done': {done: 'Y'},
      'only_undone': {done: 'N'}
    };
    
    vm.filter = vm.filteringOptions['only_done'];
  
  })

  app.controller('myController2', function($scope){
      $scope.statuses = [{
        id: 1,
        name: "First Value"        
    }, {
        id: 2,
        name: "Second Value"        
    }, {
        id: 3,
        name: "Third Value"        
    }, {
        id: 4,
        name: "Fourth Value"        
    }, {
        id: '',
        name: "All"        
    }];
    $scope.selected_status = 3;
     $scope.data = [
            { id: 1, name: "Max"},
            { id: 2, name: "Adam"},
            { id: 3, name: "Betty" },
            { id: 4, name: "Sara"  },
            { id: 5, name: "Arun"  }
            
        ];
  
  })

  app.directive('bsDropdown', function ($compile) {
    return {
        restrict: 'E',
        scope: {
            items: '=dropdownData',
            doSelect: '&selectVal',
            selectedItem: '=preselectedItem'
        },
        link: function (scope, element, attrs) {
            var html = '';
            switch (attrs.menuType) {
                case "button":
                    html += '<div class="btn-group"><button class="btn button-label btn-info">Action</button><button class="btn btn-info dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>';
                    break;
                default:
                    html += '<div class="dropdown"><a class="dropdown-toggle" role="button" data-toggle="dropdown"  href="javascript:;">Dropdown<b class="caret"></b></a>';
                    break;
            }
            html += '<ul class="dropdown-menu"><li ng-repeat="item in items"><a tabindex="-1" data-ng-click="selectVal(item)">{{item.name}}</a></li></ul></div>';
            element.append($compile(html)(scope));
            for (var i = 0; i < scope.items.length; i++) {
                if (scope.items[i].id === scope.selectedItem) {
                    scope.bSelectedItem = scope.items[i];
                    break;
                }
            }
            scope.selectVal = function (item) {
                switch (attrs.menuType) {
                    case "button":
                        $('button.button-label', element).html(item.name);
                        break;
                    default:
                        $('a.dropdown-toggle', element).html('<b class="caret"></b> ' + item.name);
                        break;
                }
                scope.doSelect({
                    selectedVal: item.id
                });
            };
            scope.selectVal(scope.bSelectedItem);
        }
    };
});




  
<link href="http://st.pimg.net/cdn/libs/bootstrap/2.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
  <script src = "http://st.pimg.net/cdn/libs/jquery/1.8/jquery.min.js">
</script>
<script src = "http://st.pimg.net/cdn/libs/bootstrap/2/js/bootstrap.min.js">
</script>

   <body ng-app="pof">
  
    <div ng-controller="myController2 as myCtrl2">
      
<bs-dropdown data-menu-type="button" select-val="selected_status = selectedVal"
preselected-item="selected_status" data-dropdown-data="statuses"></bs-dropdown>  &nbsp; Selected Value : {{selected_status}}

<ul ng-repeat="item in data | filter: selected_status">
        <li>{{item.id}} {{item.name}}</li>
 </ul>
    </div>    
   
</body>