Angular 5实现当前登录用户在ngFor数组中置顶
我来帮你搞定这个需求!你想要把当前登录用户固定在数组第一位的想法很清晰,咱们可以从修复管道和在数据流源头处理两种方案入手,后者其实更推荐,性能和维护性都更好,先给你逐一说明:
方案一:修正你的FilterActive管道
先说说你当前管道存在的两个核心问题:
- 参数类型定义错误,
array应该是iUser[]而非Array<string> - 排序比较函数必须返回数字(-1/0/1),而不是直接返回对象,这是JS数组
sort方法的硬性要求
下面是修正后的完整管道代码:
import { Pipe, PipeTransform } from '@angular/core'; import { iUser } from './path-to-your-interface'; // 记得导入你的用户接口 @Pipe({ name: 'filterActive', pure: false // 如果用户列表是动态更新的,需要设置为非纯管道;若用不可变数据更新,可保持pure: true }) export class FilterActivePipe implements PipeTransform { transform(users: iUser[], args?: { activeUser: string }): iUser[] { // 空值兜底,避免报错 if (!users || !args?.activeUser) return users; // 复制原数组再排序,避免修改原数据(sort是原地排序) return [...users].sort((a, b) => { // 若a是当前用户,排到前面 if (a.uid === args.activeUser) return -1; // 若b是当前用户,a排到后面 if (b.uid === args.activeUser) return 1; // 其他用户保持原有顺序 return 0; }); } }
方案二:在Observable数据流中处理(更推荐)
正如你怀疑的,管道并非最优解——Angular纯管道只有在输入引用变化时才会执行,若用户列表是可变对象,可能需要设置pure: false,这会导致管道在每次变更检测时都执行,影响性能。更高效的方式是在数据获取时直接处理:
手动订阅时处理
修改组件中的订阅逻辑:
this.auth.getActiveUsers().subscribe( usersAvailable => { // 提取当前登录用户 const currentUser = usersAvailable.find(u => u.uid === activeAccount); // 过滤掉当前用户,保留其他用户的原有顺序 const otherUsers = usersAvailable.filter(u => u.uid !== activeAccount); // 拼接成新数组:当前用户 + 其他用户 this.usersFetched = currentUser ? [currentUser, ...otherUsers] : otherUsers; }, error => console.log(error) );
结合async管道(Angular最佳实践)
如果想省去手动管理订阅的麻烦,可以直接在Observable流中处理,搭配async管道使用:
import { map, catchError } from 'rxjs/operators'; import { of } from 'rxjs'; // 组件中定义Observable this.usersFetched$ = this.auth.getActiveUsers().pipe( map(users => { const currentUser = users.find(u => u.uid === activeAccount); const otherUsers = users.filter(u => u.uid !== activeAccount); return currentUser ? [currentUser, ...otherUsers] : otherUsers; }), catchError(error => { console.log(error); return of([]); // 出错时返回空数组兜底 }) );
模板中直接用async管道渲染:
<ion-row *ngFor="let i of rows"> <div class="o-userGrid__item" (click)="openItem(u)" *ngFor="let u of usersFetched$ | async" width-33> <img [src]="u?.photoURL" /> <div class="o-userGrid__title"> {{ u?.displayName }} </div> </div> </ion-row>
这种方式不用手动订阅/取消订阅,Angular会自动管理,更符合框架的设计理念。
内容的提问来源于stack exchange,提问作者Kravitz
相关产品推荐
相关产品推荐

