AngularJS:使用数组过滤器的不同方法

AngularJS提供了过滤器功能,可用于格式化输入值或过滤具有给定匹配输入条件的数组。 例如,您可以使用“日期”过滤器将日期值格式化为易于理解的日期表示形式,例如MM-DD-YYYY{{dob | 日期}}

另一方面,还有数组过滤功能,在过滤来自JavaScript对象数组的数据时非常有用。 Array过滤非常常与Table和
ng-repeat指令。

例如,我们可以有一个待办事项列表,可以使用ng-repeat标签将其显示在表格中。 我们可以有一个文本字段来搜索待办事项,该待办事项与Todo对象的任何数据属性相匹配,如下所示:

$scope.todos = [
    {id: 1,title: 'Learn AngularJS', description: 'Learn AngularJS', done: true, date: new Date()}  ,
    {id: 2,title: 'Explore ui-router', description: 'Explore and use ui-router instead of ngRoute', done: true, date: new Date()}  ,
    {id: 3,title: 'Play with Restangular', description: 'Restangular seems better than $resource, have a look', done: false, date: new Date()}  ,
    {id: 4,title: 'Try yeoman', description: 'No more labour work..use Yeoman', done: false, date: new Date()}  ,
    {id: 5,title: 'Try MEANJS', description: 'Aah..MEANJS stack seems cool..why dont u try once', done: false, date: new Date()}                
            ];

 
<input type="text" ng-model="searchTodos">
 <table class="table table-striped table-bordered">
 <thead>
  <tr>
   <th>#</th>
   <th>Title</th>
   <th>Description</th>
   <th>Done?</th>
   <th>Date</th>
  </tr>
 </thead>
 <tbody>
  <tr ng-repeat="todo in todos| filter: searchTodos">
   <td>{{$index + 1}}</td>
   <td>{{todo.title}}</td>
   <td>{{todo.description}}</td> 
   <td>{{todo.done}}</td>
   <td>{{todo.date | date}}</td> 
  </tr>

 </tbody>

</table>

观察我们的搜索输入字段的ng-model属性设置为' searchTodos ,我们已经使用它来过滤ng-repeat属性。 在搜索输入字段中键入内容时, $ scope.todos数组将被过滤,并且仅显示匹配的记录。 这是一个“ 任何条件都匹配 ”类型的过滤器,这意味着将根据Todo对象的所有属性( id,title,description,date )检查搜索条件。

如果您只想在一个字段(例如“ description ”)上进行搜索,则可以按以下方式应用过滤器:

<tr ng-repeat="todo in todos| filter: {description: searchTodos}">

如果您只想显示尚未完成的待办事项,则可以按以下步骤进行:

<tr ng-repeat="todo in todos| filter: {description: searchTodos, done: false}">

请注意,这里将使用AND条件应用这两个条件。

如果您只想显示尚未完成的待办事项,并且要搜索所有字段,而不仅仅是在' description '上,那么可以按照以下步骤进行操作:

<tr ng-repeat="todo in todos| filter: {$: searchTodos, done: false}">

$表示所有字段。 到目前为止,这是一个简单明了的案例。

如何在Array对象中嵌套对象,而我们想基于嵌套对象属性进行搜索呢?

让我们看看这种情况。 为了解释这些情况,我使用了ebuddy应用程序中的一些代码示例。

在我的ebuddy应用程序中,我有一个ExpenseManager模块,在这里我将跟踪支出情况,如下所示:

  • 我将有一个帐户列表,例如现金,储蓄银行帐户,信用卡等,并带有当前余额详细信息。
  • 我将有一个收款人清单,例如HouseRent,PowerBill,Salary等,属于收入或支出类别。
  • 我将选择一个帐户,一个收款人和金额来记录我的所有交易。

此应用程序仅用于记录我的财务交易,以便我可以按帐户或收款人的名义查看月度报告。 希望您对域模型有所了解。

现在让我们创建一个简单的AngularJS应用程序并设置一些示例数据。

<!DOCTYPE html>
 <html ng-app="myApp">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>My AngularJS App</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/js/bootstrap.min.js"></script>
  
  <script>
      var myApp = angular.module('myApp',[]);
      myApp.controller('SampleController', function($scope){
            $scope.accounts = [ 
                    {id: 1, name: 'Cash'}, 
                    {id: 2, name: 'Bank Savings'} 
                  ];
            $scope.payees = [
                    {id:'1',name:'HouseRent', txnType:'EXPENDITURE'},
                    {id: '2', name:'InternetBill', txnType:'EXPENDITURE'}, 
                    {id:'3', name: 'PowerBill', txnType:'EXPENDITURE'}, 
                    {id:'4', name: 'Salary', txnType:'INCOME'}
                  ];
            $scope.transactions = [
                {id:'1', txnType:'EXPENDITURE', amount: 1000, account: $scope.accounts[0], payee: $scope.payees[0]},
                {id:'2', txnType:'EXPENDITURE', amount: 500, account: $scope.accounts[1], payee: $scope.payees[1]},
                {id:'3', txnType:'EXPENDITURE', amount: 1200, account: $scope.accounts[0], payee: $scope.payees[1]},
                {id:'4', txnType:'INCOME', amount: 5000, account: $scope.accounts[1], payee: $scope.payees[3]},
                {id:'5', txnType:'EXPENDITURE', amount:200, account: $scope.accounts[0], payee: $scope.payees[2]}
            ];
            
      });
      
  </script>  
</head>
<body ng-controller="SampleController">
<br/>
 <div class="col-md-8 col-md-offset-2">
        
    <h3>Transaction Details</h3>
    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <th>#</th>
                <th>Account</th>
                <th>Type</th>
                <th>Payee</th>
                <th>Amount</th>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="txn in transactions">
                <td>{{$index + 1}}</td>
                <td>{{txn.account.name}}</td>
                <td>{{txn.txnType}}</td> 
                <td>{{txn.payee.name}}</td> 
                <td>{{txn.amount}}</td> 
            </tr>
        </tbody>
    </table>
</div>

</body>
</html>

这是一个非常简单的AngularJS页面,它在表中显示事务列表。 观察到事务包含嵌套对象( accountpayee ),并且我们在表中显示嵌套属性( txn.account.nametxn.payee.name )。

现在,我们想以各种方式过滤交易,因此让我们逐案研究。

案例1:按收款人姓名搜索

在我们的交易对象中,我们有一个嵌套的收款人对象,其中包含要对其进行搜索的name属性。

让我们创建一个表单,该表单将在事务表之前包含所有过滤器。

我想到对嵌套属性执行搜索的第一个想法是使用filter中的嵌套属性路径,如下所示:

<input type="text" ng-model="payeeName">
...
<tr ng-repeat="txn in transactions| filter: {payee.name : payeeName}">

但是,这是可行的。

要搜索嵌套属性,我们可以将输入字段ng-model命名为与目标属性路径匹配,并使用根对象名称作为过滤器,如下所示:

<div class="col-md-8 col-md-offset-2">
     <form class="form-horizontal" role="form">
        <div class="form-group">
          <label for="input1" class="col-sm-4 control-label">Search by Payee</label>
          <div class="col-sm-6">
            <input type="text" class="form-control" id="input1" placeholder="Payee Name" ng-model="filterTxn.payee.name">
          </div>
        </div>
  <!-- additional filters will come here -->
 </form>
 <h3>Transaction Details</h3>
 <table class="table table-striped table-bordered">
  ...
  <tbody>
            <tr ng-repeat="txn in transactions| filter: filterTxn">
                ...
    ...
            </tr>
  </tbody>
 </table>
</div>

观察到我们已经将输入字段ng-model绑定到“ filterTxn.payee.name ”,并使用filter: filterTxn作为filter。 因此, txn.payee.name将与filterTxn.payee.name匹配。

案例2:按帐户过滤下拉列表

我们想使用“帐户选择”下拉列表过滤交易。 首先,我们需要使用$ scope.accounts填充选择下拉列表,并将其用作过滤器。

在我们的第一个过滤器之后添加以下过滤器。

<div class="form-group">
  <label for="input2" class="col-sm-4 control-label">Search By Account</label>
  <div class="col-sm-6">
  <select id="input2" class="form-control" ng-model="filterTxn.account">
   <option value="">All Accounts</option>
   <option ng-repeat="item in accounts" value="{{item.id}}">{{item.name}}</option>
  </select>
  </div>
</div>

在这里,我们通过显示“帐户名称”并使用id作为值来用$ scope.accounts数组填充<select>字段。

这里的关键部分是我们将ng-model绑定到filterTxn.account 。 当我们选择一个帐户时,选定的帐户对象引用将存储在filterTxn.account中 。 由于我们已经使用filterTxn作为过滤器,因此帐户过滤器也将与收款人姓名过滤器一起应用。

还要注意,第一个选项“ All Accounts”的值是空的( “” ),AngularJS将其视为空值 ,因此,当选择“ All Accounts”选项时,将不会应用任何帐户过滤器。

案例3:按交易类型搜索

我们要按事务类型( INCOMEEXPENDITURE )过滤事务:

在第二个过滤器之后添加以下过滤器:

<div class="form-group">
  <label for="input3" class="col-sm-4 control-label">Search By Type</label>
  <div class="col-sm-6">
  <select id="input3" class="form-control" ng-model="filterTxn.txnType">
   <option value="">All Types</option>
   <option value="EXPENDITURE">EXPENDITURE</option>
   <option value="INCOME">INCOME</option>
  </select>
  </div>
</div>

我希望不需要进一步的解释!

案例4:按支出类型的收款人搜索

Aaah ..这很有趣! 我们只想按收款人姓名搜索,但只能搜索“ 支出”类型的收款人。

我们不能简单地应用“ filter:expPayeeFilter | filter:{txnType:'EXPENDITURE'}“,因为它将始终按EXPENDITURE进行过滤。

因此,我们将创建一个自定义过滤器,以执行“ 仅当输入了某些过滤器文本时,才在EXPENDITURE类型的收款人中按收款人姓名搜索 ”:

myApp.filter('expenditurePayeeFilter', [function($filter) {
 return function(inputArray, searchCriteria, txnType){         
  if(!angular.isDefined(searchCriteria) || searchCriteria == ''){
   return inputArray;
  }         
  var data=[];
  angular.forEach(inputArray, function(item){             
   if(item.txnType == txnType){
    if(item.payee.name.toLowerCase().indexOf(searchCriteria.toLowerCase()) != -1){
     data.push(item);
    }
   }
  });      
  return data;
 };
}]);

我们使用myApp.filter()创建了一个自定义过滤器,并在其中使用了angular.forEach()遍历输入数组,其余的都是纯JavaScript..no魔术。

现在,我们将如下应用此自定义过滤器:

<tr ng-repeat="txn in transactions| filter: filterTxn | expenditurePayeeFilter:searchCriteria:'EXPENDITURE'">
 <td>{{$index + 1}}</td>
 <td>{{txn.account.name}}</td>
 <td>{{txn.txnType}}</td> 
 <td>{{txn.payee.name}}</td> 
 <td>{{txn.amount}}</td> 
</tr>

观察语法: customFilterName:param1:param2:..:paramN

这些参数将作为参数传递给自定义指令中的函数。

关于如何使用AngularJS数组过滤功能,我们没有看到一些有趣的选项。

希望能帮助到你!

翻译自: https://www.javacodegeeks.com/2014/09/angularjs-different-ways-of-using-array-filters.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值