Angular:TypeScript 中的搜索栏 table
Angular: Search bar in TypeScript table
我已经完成了一个简单的 CRUD 应用程序,现在我必须添加一个搜索栏来过滤我的 table 并显示与我数字相同的字母的行。
我不知道在我的组件中做什么,我看到管道和过滤器有不同的东西,但我无法使它们适应我的项目。
我想知道是否有一种方法可以在我的 component.ts 中实施而无需创建新方法。
COMPONENT.HTML
<div class="container">
<ul class="table-wrapper">
<div class="table-title">
<div class="row">
<div class="col-sm-4">
<button *ngIf="metadata && metadata.addMD" (click)="addFunc(metadata)">{{metadata.addMD.label}}</button>
<div class="show-entries">
<span>Show</span>
<label>
<select [(ngModel)]="pageSize">
<option *ngFor="let maxPerPage of rowsOnPageSet"
(click)="maxElements(maxPerPage)">{{maxPerPage}}</option>
</select>
</label>
<span>users</span>
</div>
</div>
<div class="col-sm-4">
<h2 class="text-center">Users <b>Details</b></h2>
</div>
<div class="col-sm-4">
<div class="search-box">
<div class="input-group">
<span class="input-group-addon"><i class="material-icons"></i></span>
--> //HERE I HAVE TO ADD THE FUNCTION OR SOMETHING ELSE
<input type="text" class="form-control" [(ngModel)]="searchVal"
(ngModelChange)='checkSearchVal()' placeholder="Search…">
</div>
</div>
</div>
</div>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th *ngFor="let col of columns" (click)="sortTable(col)">{{col}}
<i *ngIf="col === columnSorted && !direction" class="material-icons">keyboard_arrow_up</i>
<i *ngIf="col === columnSorted && direction" class="material-icons">keyboard_arrow_down</i>
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | paginate: {itemsPerPage: pageSize,
currentPage: page,
totalItems: users.length}">
<td *ngFor="let col of columns">{{user[col]}}</td>
<td>
<button [ngClass]="getClassCondition(act.actionType)" *ngFor="let act of actions"
(click)="actionFunc(act, user)">{{act.label}}</button>
</td>
</tr>
</tbody>
</table>
<div align="center">
<!--<div class="hint-text">Showing <b>{{totUsersPerPage}}</b> out of <b>{{users.length}}</b> entries</div>-->
<ul align="center">
<pagination-controls (pageChange)="pageChanged($event)"></pagination-controls>
</ul>
</div>
</ul>
</div>
COMPONENT.TS,在这里我必须创建适用于我的应用程序的正确方法。
export class DynamicTableComponent implements OnInit {
constructor(private userService: UserService,
private resourcesService: ResourcesService,
private router: Router) {
}
@Input()
users = [];
@Input()
columns: string[];
@Input()
actions = [];
@Input()
metadata: any;
@Input()
class;
direction = false;
columnSorted = '';
public rowsOnPageSet = ['5', '10', '15', '20', '25'];
page = 1;
private pageSize = 5;
searchVal = '';
/*totalPages = Math.trunc(this.users.length / this.pageSize);
totUsersPerPage = this.pageSize;*/
ngOnInit() {
}
actionFunc(action, element: any) {
if (action.actionType === 'DELETE') {
/*...*/
}
}
if (action.actionType === 'GO_TO') {
/*...*/
}
}
addFunc(metadata) {
if (metadata.addMD.actionType === 'ADD_TO') {
/*...*/
}
}
maxElements(maxPerPage) {
this.rowsOnPageSet = maxPerPage;
}
sortTable(param) {
/*...*/
}
getClassCondition(act) {
return act === 'DELETE' ? this.class = 'btn btn-danger' : 'btn btn-primary';
}
pageChanged($event: number) {
/*...*/
}
checkSearchVal() {
this.users.slice();
const filteredUsers: User[] = [];
if (this.searchVal && this.searchVal !== '') {
for (const selectedUser of this.users) {
if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) !== -1 ||
selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) !== -1) {
filteredUsers.push(selectedUser);
}
}
this.users = filteredUsers.slice();
}
}
}
数据结构:
in.memory-data.service.ts
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { User } from './user';
import { Injectable } from '@angular/core';
export const COLUMNS = ['id', 'firstName', 'lastName', 'age'];
@Injectable({
providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const USERS = [
{id: 1, firstName: 'NAME_1', lastName: 'SURNAME_1', age: 23},
{id: 2, firstName: 'NAME_2', lastName: 'SURNAME_2', age: 23},
{id: 3, firstName: 'NAME_3', lastName: 'SURNAME_3', age: 23},
{id: 4, firstName: 'NAME_4', lastName: 'SURNAME_4', age: 24},
{id: 5, firstName: 'NAME_5', lastName: 'SURNAME_5', age: 42},
{id: 6, firstName: 'NAME_6', lastName: 'SURNAME_6', age: 41},
{id: 7, firstName: 'NAME_7', lastName: 'SURNAME_7', age: 24},
{id: 8, firstName: 'NAME_8', lastName: 'SURNAME_8', age: 25},
{id: 9, firstName: 'NAME_9', lastName: 'SURNAME_9', age: 25},
{id: 10, firstName: 'NAME_10', lastName: 'SURNAME_10', age: 25},
{id: 11, firstName: 'NAME_11', lastName: 'SURNAME_11', age: 22},
{id: 12, firstName: 'NAME_12', lastName: 'SURNAME_12', age: 22},
{id: 13, firstName: 'NAME_13', lastName: 'SURNAME_13', age: 24},
];
return {USERS};
}
}
user.ts
export class User {
id: number;
firstName: string;
lastName: string;
age: number;
}
只需创建一个 PIPE.ts 文件来过滤 table:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterAll'
})
export class FilterPipe implements PipeTransform {
transform(value: any, searchText: any): any {
if(!searchText) {
return value;
}
return value.filter((data) => this.matchValue(data,searchText));
}
matchValue(data, value) {
return Object.keys(data).map((key) => {
return new RegExp(value, 'gi').test(data[key]);
}).some(result => result);
}
}
将 FilterPipe 添加到 app.module.ts 中的 declarations
并将其添加到您的 component.html:
<form id="searchForm">
<div class="form-group">
<div class="input-group" id="filterAll">
<div class="input-group-addon"><i class="glyphicon glyphicon-search"></i></div>
<input type="text" class="form-control" name="searchString" placeholder="Search..." [(ngModel)]="searchString">
</div>
</div>
</form>
然后像这样向 table 的 TR 添加管道:
<tr *ngFor="let user of users | paginate: {itemsPerPage: pageSize,
currentPage: page,
totalItems: users.length} | filterAll: searchString">
我忘记了 component.ts 文件抱歉:
您需要将 searchString 变量设置为:
public searchString: string;
我看到你得到了答案...here 是另一种有价值的方法...正如评论中所讨论的...
checkSearchVal() {
this.USERS = masterUSERS.slice();
let filteredUsers: User[] = [];
if (this.searchVal && this.searchVal != '') {
/* NORMAL FOR
for(var i=0; i<this.USERS.length; i++ ){
if(this.USERS[i].firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 || this.USERS[i].lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ){
filteredUsers.push(this.USERS[i])
}
}
*/
/* FOR EACH
this.USERS.forEach((selectedUser) => {
if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ||
selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1) {
filteredUsers.push(selectedUser);
}
})
*/
/* FOR OF */
for (let selectedUser of this.USERS) {
if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ||
selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1) {
filteredUsers.push(selectedUser);
}
}
this.USERS = filteredUsers.slice();
}
}
更新:移动了this.USERS = filteredUsers.slice();在 IF
内
更新:2:与 forEach 和 For-Of 相同的代码(消除 TSLint 错误)
我已经完成了一个简单的 CRUD 应用程序,现在我必须添加一个搜索栏来过滤我的 table 并显示与我数字相同的字母的行。
我不知道在我的组件中做什么,我看到管道和过滤器有不同的东西,但我无法使它们适应我的项目。
我想知道是否有一种方法可以在我的 component.ts 中实施而无需创建新方法。
COMPONENT.HTML
<div class="container">
<ul class="table-wrapper">
<div class="table-title">
<div class="row">
<div class="col-sm-4">
<button *ngIf="metadata && metadata.addMD" (click)="addFunc(metadata)">{{metadata.addMD.label}}</button>
<div class="show-entries">
<span>Show</span>
<label>
<select [(ngModel)]="pageSize">
<option *ngFor="let maxPerPage of rowsOnPageSet"
(click)="maxElements(maxPerPage)">{{maxPerPage}}</option>
</select>
</label>
<span>users</span>
</div>
</div>
<div class="col-sm-4">
<h2 class="text-center">Users <b>Details</b></h2>
</div>
<div class="col-sm-4">
<div class="search-box">
<div class="input-group">
<span class="input-group-addon"><i class="material-icons"></i></span>
--> //HERE I HAVE TO ADD THE FUNCTION OR SOMETHING ELSE
<input type="text" class="form-control" [(ngModel)]="searchVal"
(ngModelChange)='checkSearchVal()' placeholder="Search…">
</div>
</div>
</div>
</div>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th *ngFor="let col of columns" (click)="sortTable(col)">{{col}}
<i *ngIf="col === columnSorted && !direction" class="material-icons">keyboard_arrow_up</i>
<i *ngIf="col === columnSorted && direction" class="material-icons">keyboard_arrow_down</i>
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | paginate: {itemsPerPage: pageSize,
currentPage: page,
totalItems: users.length}">
<td *ngFor="let col of columns">{{user[col]}}</td>
<td>
<button [ngClass]="getClassCondition(act.actionType)" *ngFor="let act of actions"
(click)="actionFunc(act, user)">{{act.label}}</button>
</td>
</tr>
</tbody>
</table>
<div align="center">
<!--<div class="hint-text">Showing <b>{{totUsersPerPage}}</b> out of <b>{{users.length}}</b> entries</div>-->
<ul align="center">
<pagination-controls (pageChange)="pageChanged($event)"></pagination-controls>
</ul>
</div>
</ul>
</div>
COMPONENT.TS,在这里我必须创建适用于我的应用程序的正确方法。
export class DynamicTableComponent implements OnInit {
constructor(private userService: UserService,
private resourcesService: ResourcesService,
private router: Router) {
}
@Input()
users = [];
@Input()
columns: string[];
@Input()
actions = [];
@Input()
metadata: any;
@Input()
class;
direction = false;
columnSorted = '';
public rowsOnPageSet = ['5', '10', '15', '20', '25'];
page = 1;
private pageSize = 5;
searchVal = '';
/*totalPages = Math.trunc(this.users.length / this.pageSize);
totUsersPerPage = this.pageSize;*/
ngOnInit() {
}
actionFunc(action, element: any) {
if (action.actionType === 'DELETE') {
/*...*/
}
}
if (action.actionType === 'GO_TO') {
/*...*/
}
}
addFunc(metadata) {
if (metadata.addMD.actionType === 'ADD_TO') {
/*...*/
}
}
maxElements(maxPerPage) {
this.rowsOnPageSet = maxPerPage;
}
sortTable(param) {
/*...*/
}
getClassCondition(act) {
return act === 'DELETE' ? this.class = 'btn btn-danger' : 'btn btn-primary';
}
pageChanged($event: number) {
/*...*/
}
checkSearchVal() {
this.users.slice();
const filteredUsers: User[] = [];
if (this.searchVal && this.searchVal !== '') {
for (const selectedUser of this.users) {
if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) !== -1 ||
selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) !== -1) {
filteredUsers.push(selectedUser);
}
}
this.users = filteredUsers.slice();
}
}
}
数据结构: in.memory-data.service.ts
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { User } from './user';
import { Injectable } from '@angular/core';
export const COLUMNS = ['id', 'firstName', 'lastName', 'age'];
@Injectable({
providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const USERS = [
{id: 1, firstName: 'NAME_1', lastName: 'SURNAME_1', age: 23},
{id: 2, firstName: 'NAME_2', lastName: 'SURNAME_2', age: 23},
{id: 3, firstName: 'NAME_3', lastName: 'SURNAME_3', age: 23},
{id: 4, firstName: 'NAME_4', lastName: 'SURNAME_4', age: 24},
{id: 5, firstName: 'NAME_5', lastName: 'SURNAME_5', age: 42},
{id: 6, firstName: 'NAME_6', lastName: 'SURNAME_6', age: 41},
{id: 7, firstName: 'NAME_7', lastName: 'SURNAME_7', age: 24},
{id: 8, firstName: 'NAME_8', lastName: 'SURNAME_8', age: 25},
{id: 9, firstName: 'NAME_9', lastName: 'SURNAME_9', age: 25},
{id: 10, firstName: 'NAME_10', lastName: 'SURNAME_10', age: 25},
{id: 11, firstName: 'NAME_11', lastName: 'SURNAME_11', age: 22},
{id: 12, firstName: 'NAME_12', lastName: 'SURNAME_12', age: 22},
{id: 13, firstName: 'NAME_13', lastName: 'SURNAME_13', age: 24},
];
return {USERS};
}
}
user.ts
export class User {
id: number;
firstName: string;
lastName: string;
age: number;
}
只需创建一个 PIPE.ts 文件来过滤 table:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterAll'
})
export class FilterPipe implements PipeTransform {
transform(value: any, searchText: any): any {
if(!searchText) {
return value;
}
return value.filter((data) => this.matchValue(data,searchText));
}
matchValue(data, value) {
return Object.keys(data).map((key) => {
return new RegExp(value, 'gi').test(data[key]);
}).some(result => result);
}
}
将 FilterPipe 添加到 app.module.ts 中的 declarations 并将其添加到您的 component.html:
<form id="searchForm">
<div class="form-group">
<div class="input-group" id="filterAll">
<div class="input-group-addon"><i class="glyphicon glyphicon-search"></i></div>
<input type="text" class="form-control" name="searchString" placeholder="Search..." [(ngModel)]="searchString">
</div>
</div>
</form>
然后像这样向 table 的 TR 添加管道:
<tr *ngFor="let user of users | paginate: {itemsPerPage: pageSize,
currentPage: page,
totalItems: users.length} | filterAll: searchString">
我忘记了 component.ts 文件抱歉: 您需要将 searchString 变量设置为:
public searchString: string;
我看到你得到了答案...here 是另一种有价值的方法...正如评论中所讨论的...
checkSearchVal() {
this.USERS = masterUSERS.slice();
let filteredUsers: User[] = [];
if (this.searchVal && this.searchVal != '') {
/* NORMAL FOR
for(var i=0; i<this.USERS.length; i++ ){
if(this.USERS[i].firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 || this.USERS[i].lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ){
filteredUsers.push(this.USERS[i])
}
}
*/
/* FOR EACH
this.USERS.forEach((selectedUser) => {
if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ||
selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1) {
filteredUsers.push(selectedUser);
}
})
*/
/* FOR OF */
for (let selectedUser of this.USERS) {
if (selectedUser.firstName.toLowerCase().search(this.searchVal.toLowerCase()) != -1 ||
selectedUser.lastName.toLowerCase().search(this.searchVal.toLowerCase()) != -1) {
filteredUsers.push(selectedUser);
}
}
this.USERS = filteredUsers.slice();
}
}
更新:移动了this.USERS = filteredUsers.slice();在 IF
内更新:2:与 forEach 和 For-Of 相同的代码(消除 TSLint 错误)