【问题标题】:select with ngOptions to select filter of another array使用 ngOptions 选择以选择另一个数组的过滤器
【发布时间】:2015-12-16 16:52:11
【问题描述】:

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

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

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

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

  1. 显示所有任务。
  2. 仅显示已完成的任务。
  3. 仅显示未完成的任务。

我所做的是设置一个带有选项的数组,以及一个在我重复 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>

Only problem is that the code above doesn't work, when the first item of the array is selected (all: '') it works fine, but I when I click the select and change it to one of the other options,它不起作用。

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

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

这种方法效果很好,我在输入中输入“Y”或“N”,它会按预期过滤myTasks。所以我认为选择错误地设置了tasksCtrl.filter,所以我在selectinput 顶部放置了一个值为tasksCtrl.filter 的div,并测试了它们以查看我会得到什么。

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

{"done": "Y"}

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

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

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

【问题讨论】:

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


【解决方案1】:

// 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'];
  
  })
;
<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>

【讨论】:

  • 我只需要过滤done 字段。我不能用“Y”过滤整个数组,因为task 字段中也会有“Y”。整个问题就是因为这个。
  • 是的,它按照您指出的方式工作......但我不能强制数组按myCtrl2.filter.done 过滤,因为选择中会有其他过滤器。 (如果我将上面的代码更改为按myCtrl2.filter 过滤,它将无法再次工作)
  • 你能给我的答案打勾和排名吗?
  • 你的回答不对,我在问题中提到的问题依然存在
  • 现在尝试使用 jquery filter.. 来过滤数据
【解决方案2】:

// 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>
 

【讨论】:

    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2017-12-26
    • 2018-11-30
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    相关资源
    最近更新 更多