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页面,它在表中显示事务列表。 观察到事务包含嵌套对象( account , payee ),并且我们在表中显示嵌套属性( txn.account.name , txn.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:按交易类型搜索
我们要按事务类型( INCOME或EXPENDITURE )过滤事务:
在第二个过滤器之后添加以下过滤器:
<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