angularjs自定义过滤器使用方法

了解为什么 Angular 不附带过滤和排序管道以及如何创建自定义过滤管道

七爪源码:为什么以及如何在 Angular 中创建不纯的过滤器管道

Angular 为最常见的场景提供了几个内置管道。

最大的缺席之一是过滤管。 Angular 不提供内置过滤器管道是有充分理由的。

为什么 Angular 不附带过滤管

Angular 中没有用于过滤和排序列表的管道,尽管 AngularJS 曾经提供 filter 和 orderBy。

这不是一个错误。

因为这样的管道性能很差并且禁止激进的缩小,Angular 并没有开箱即用地提供它们。 过滤成本很高。

尽管计算能力每年都在增长,但数据和信息也在不断增长!

七爪源码:为什么以及如何在 Angular 中创建不纯的过滤器管道

一般来说,过滤需要与对象属性对应的参数。 然而,有些场景要求管道是不纯的,这意味着 Angular 几乎在每次更改检测周期发生时都会调用不纯管道。

因此,过滤和排序成为代价高昂的操作,尤其是在数据量很大的情况下。

当 Angular 每秒多次调用这些管道时,即使是中等大小的列表,用户体验也可能会受到很大影响。

如何创建纯 FilterPipe

首先,让我们看一下模板和类。

应用组件和数据

在模板中,我们有一个输入元素,它使用双向绑定将用户输入存储在一个名为 filterBy 的属性中。 请记住在 AppModule 中导入 FormsModule 以在您的应用程序中使用双向绑定。

下面,我们使用 NgFor 从 usersList 中列出一些用户的名字。 这是代码:

<div> <label for="filter">Filter by: </label> <input type="text" id="filter" [(ngModel)]="filterBy" /></div><div *ngFor="let user of usersList> <ul> <li>{{ user.name }}</li> </ul></div>

import { Component, VERSION } from '@angular/core';import { User } from './model';@Component({ selector: 'my-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'],})export class AppComponent { name = 'Angular ' + VERSION.major; filterBy; usersList: User[] = [...] // omitted for clarity}

用户列表 usersList 是一个包含十个项目的数组,例如 users。 它存储在类中,您可以在 jsonplaceholder 或此应用的 StackBlitz 中找到它。

每个用户都是一个具有多个属性的对象。 对于我们的目的,知道其中一个属性是名称就足够了。

我们想按名称过滤用户。

初始应用程序如下所示:

七爪源码:为什么以及如何在 Angular 中创建不纯的过滤器管道

创建 FilterPipe 类

让我们从使用 Angular CLI 命令 ng generate pipe filter 开始,其中 filter 是将在模板绑定中使用的管道名称。

作为旁注,您还可以使用 ng g p 管道。

Angular 将负责创建文件、填充一些字段并将其正确导入 app.module.ts。

import { Pipe, PipeTransform } from '@angular/core';@Pipe({ name: 'filter'})export class FilterPipe implements PipeTransform { transform(value: any, args?: any): any { return null; }}

在 transform 方法中,value 是模板中管道左侧的值,而 args? 是我们将用于过滤值的可选参数。

要使用此过滤器,我们只需将其添加到模板中,如下所示:

<div *ngFor="let user of usersList | filter">

自然,什么都不会发生。但是,请注意 usersList 是通过管道的属性,并且与 transform 方法中的 value 参数相关联。

将过滤代码添加到 FilterPipe

我们现在将在 FilterPipe 中的 transform 方法中工作。

变换方法的参数

首先,我们使用以下代码更新 transform 方法的参数:

transform(value: User[], filterString: string, property: string)

我们在上面讨论了价值。值的类型是形状像用户界面的对象数组。您可以在 StackBlitz 的 model.ts 中看到这一点。

第二个参数是 string 类型的 filterString。 filterString 的值必须来自模板。因此,我们将向管道添加一个参数。参数将是 filterBy ,即用户输入,例如,用户想要用作过滤器的字符串。

第三个也是最后一个论点是财产。由于我们的用户对象包含多个属性,因此我们需要指定要使用的属性。为了简单起见,我将字符串名称硬编码为模板中过滤器管道的第二个参数。

这是一个例子。通常,您不应该在代码中硬编码值。

在模板中,管道变为:

...<div *ngFor="let user of usersList | filter: filterBy:'name'"> <ul> <li>{{ user.name }}</li> </ul></div>

其中 filter 是管道的名称,filterBy 是我们从输入元素中获得的属性,这要归功于双向绑定,而 'name' 是用户对象中的硬编码属性。

您需要的参数数量是可选的,根据您的需要。

transform方法中的过滤逻辑

现在我们在 transform 方法中工作。

我们首先添加一些代码以在没有过滤器时返回每个值。

if (value.length === 0 || !filterString) { return value;}

然后,我们添加逻辑以根据用户的字符串进行过滤。

let filteredUsers: User[] = [];for (let user of value) { if (user[property].includes(filterString)) { filteredUsers.push(user); }}return filteredUsers;

请记住,属性是硬编码的,它意味着名称。 value 是 usersList 中的用户列表,filterString 是一个人想要用作过滤器的字符串,例如 filterBy。

因此,您可以将这段代码读作“对于userList中的每个用户,如果用户名包含filterBystring,则将此用户添加到filteredUsersarray”最终返回。

到目前为止,这是 FilterPipe:

import { Pipe, PipeTransform } from '@angular/core';import { User } from './model';@Pipe({ name: 'filter',})export class FilterPipe implements PipeTransform { transform(value: User[], filterString: string, property: string): User[] { if (value.length === 0 || !filterString) { return value; } let filteredUsers: User[] = []; for (let user of value) { if (user[property].toLowerCase().includes(filterString.toLowerCase())) { filteredUsers.push(user); } } return filteredUsers; }}

此时,管道允许我们很好地过滤名称。

请注意,我添加了 Javascript toLowerCase() 方法,以便过滤器不区分大小写。 当然,这完全是可选的。

那么昂贵的过滤操作呢?

如何使 FilterPipe 不纯

让我们更进一步。

我们添加一个简单的按钮,使用以下代码将新用户添加到 usersList:

<button (click)="onAddUser()">Add user</button>

该方法如下所示:

onAddUser() { this.usersList.push({ id: Math.floor(Math.random() * 10000), name: 'Leanne Graham', username: 'Bret', ... });}

每次单击时,都会将一个用户推送到 usersList。

这就是问题所在!

如果您过滤 Leanne,然后单击该按钮,则用户将添加到 usersList,但不会呈现过滤后的列表。因此,您不会在过滤列表中看到新用户,即使您在删除过滤器后会立即看到它们。

每次复合数组或对象更改时,Angular 都不会在数据上重新运行管道。

纯净和不纯净的管道

更准确地说,我们需要谈谈纯管道和非纯管道。

当输入值发生纯变化时,我们有一个纯管道。纯粹的更改可以是以下之一:

  • 对原始输入值(字符串、数字、布尔值、符号)的更改
  • 对对象引用(日期、数组、函数、对象)的更改

纯管道使用纯函数。给定相同的输入,纯函数应该总是返回相同的输出。

默认情况下,管道是纯的,因为 Angular 忽略了对象或数组内部的变化。因此,当我们添加到输入数组时,它不会调用纯管道,就像我们的例子一样,或者更新输入对象属性。

您可以猜到,对象引用检查比深度检查差异更快。此外,当 Angular 跳过管道执行时,它也会跳过视图更新。

因此,当常规变化检测策略很好时,最好使用纯管道。

当我们需要进行深度检查时,例如在当前示例中,我们需要使用不纯管道。

在每个组件变化检测周期中都会有一条不纯的管道运行。例如,它可以在每次击键或鼠标移动时运行。

你可以猜到,这很快就变得非常昂贵。

话虽如此,实现不纯管道就像在管道装饰器中声明 pure: false 一样简单。

@Pipe({ name: 'filter', pure: false,})

通过将 pure 属性添加到 Pipe 装饰器,我们强制 FilterPipe 在每次数据更改时更新。

在管道内添加一个日志以可视化频率。

使用不纯管道可能会导致性能和激进的最小化问题。 因此,请谨慎使用,仅在真正需要时使用。

在 StackBlitz 上查找代码或从 GitHub 克隆应用程序。

异步管道

作为旁注,值得一提的是异步管道是不纯的。 粗略地说,我们可以争辩说“管道总是在检查新的输入数据时是不纯的”。

虽然 Angular 异步管道优化了更改检测,但它也消除了手动使用订阅和取消订阅的必要性。

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:dandanxi6@qq.com

(0)
上一篇 2023年 2月 3日 下午12:22
下一篇 2023年 2月 3日 下午12:29

相关推荐

  • 直播行业怎么盈利,网上直播怎么盈利

    我目前了解到的盈利模式一方面是礼物的抽成,再一个就是外部广告费。内部中也会有一些推广的费用,比如上推荐之类的。 从这一点上来看那直播平台的痛点还在于怎么让看直播的人更有意愿去送礼物…

    互联网 2023年 9月 20日
  • 微信签到能做的超越你的想象吗(微信签到是怎样做出来的)

    你心目中的微信是什么样?我相信有人会说它当然就是个社交软件啊,其实不然。快会务还可以把微信放在各种活动的签到环节,不仅简便而且普及率极高。以往活动签入口处人员堆积、硬件设备要求高等…

    2023年 1月 31日
  • c语言求阶乘的累加和递归

    C语言求1+2!+3!+…+20!的和。 分析 对于累加采用for循环,设置变量sum和循环变量进行累加。 #include<stdio.h>int mai…

    2023年 5月 24日
  • 退了群之后怎样才能不被打扰,怎么避免群里关消息免打扰

    芋头问问是教父母学习使用智能手机的。 父母需要学习使用智能手机的话,转给他们看看哦~ 我们总是在无意或有意的加入各种群聊,收到的群聊消息也越来越多,但是其中很多群消息对我们来说都是…

    2023年 5月 23日
  • eshop怎么切换服务器

    很多小伙伴在Eshop商店上购买数字版游戏时想换其他地区去购买或者体验游戏,但是却不知道怎么操作,针对这个问题,小编在后文中也整理了详细的解决办法来帮助大家。 很多人在换区大多都是…

    2022年 12月 19日
  • uv与pv的区别,pvuv计算公式

    UV(Unique visitor) 是指通过互联网访问、浏览这个网页的自然人。访问您网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次。 一天内同个…

    2023年 7月 20日
  • cad常用快捷键命令表(cad命令行常用指令)

    在CAD软件操作中,我们为了方便使用,会利用快捷键代替鼠标,这样操作起来就轻松很多了。可以利用键盘快捷键发出命令,完成绘图,修改,保存等操作。这些命令键就是CAD快捷键。是不是很好…

    2022年 12月 23日
  • 优酷号申请入驻教程,优酷要先发才能入驻优酷号吗

    优酷现在正式推出自媒体平台“优酷号”,想要入驻的用户,已经可以去申请了,免费的。更多关于优酷号的内容,一起看看下文吧。 优酷号是什么 优酷正式上线短视频自媒体平台优酷号,同时向创作…

    2023年 3月 16日
  • 如何修改微信小号信息

    随着科技的发展,我们生活中越来越多的信息都被记录在了互联网上,所以我们也会更加的注重自己的隐私和信息安全,不然一不小心自己的信息就可能被各大应用、网站给记录下来。 微信在我们的生活…

    2023年 4月 13日
  • 制作情侣头像简单

    首先点开QQ的系统设置里面的资料设置,可看到在个性签名下方有个图标管理,如果图标管理中把您的业务隐藏了,您可以点取消隐藏而恢复,这样就可以看到!如果还看不到,那么您可以点开系统设置…

    2023年 2月 8日