Angular模板绑定函数返回值给子组件@Input时函数反复执行怎么办
问题根本原因
函数反复执行是Angular默认变更检测机制的正常表现:
- 模板中绑定的表达式/函数调用,会在每一轮变更检测周期被重新执行,用来校验绑定值是否发生变化
- 只要页面有任何交互(点击、滚动、输入)、异步事件返回(HTTP请求、定时器、WebSocket消息)都会触发变更检测,导致
checkFollow被反复调用 - 当前的
checkFollow还包含了split、遍历操作,频繁执行会带来不必要的性能损耗
优化方案
方案1:提前预处理关注状态(性能最优)
在获取speakers列表、或者dataUser.userFollowing更新的时候,提前把每个用户的关注状态算好,存在speakers的对象属性里,模板直接绑定属性即可:
// 在获取speakers或者userFollowing更新后执行预处理 preprocessFollowStatus() { // 提前转成Set提升查找效率 const followingSet = new Set(this.dataUser.userFollowing.split(',')); this.speakers = this.speakers.map(user => ({ ...user, isFollowed: followingSet.has(user.userId.toString()) })) }
模板修改为直接绑定预处理好的属性:
<image-card *ngFor="let user of speakers; let i = index" [_follow]="user.isFollowed"></image-card>
该方案计算逻辑只会在依赖数据更新的时候执行一次,无多余性能消耗。
方案2:封装为纯管道
如果确实需要在模板中做计算,你可以把判断关注的逻辑封装成纯管道,Angular只有在输入参数发生变化的时候才会重新执行管道逻辑:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'isFollowed' }) export class IsFollowedPipe implements PipeTransform { transform(userId: number, followingListStr: string): boolean { const followingSet = new Set(followingListStr.split(',')); return followingSet.has(userId.toString()); } }
模板使用管道:
<image-card *ngFor="let user of speakers; let i = index" [_follow]="user.userId | isFollowed:dataUser.userFollowing"></image-card>
内容的提问来源于stack exchange,提问作者Sebastián Rodríguez
相关产品推荐
相关产品推荐

