用功能Angular 8替换链式过滤器/顺序管道

问题描述 投票:0回答:2

现在按angular docs

过滤,尤其是分类是昂贵的操作。当Angular每秒多次调用这些管道方法时,即使是中等大小的列表,用户体验也会严重恶化。 filter和orderBy经常在AngularJS应用中被滥用,导致人们抱怨Angular本身运行缓慢。

我已经在我的应用程序中创建了一个过滤器/订单和搜索管道-最初的性能不是问题,但现在却引起了一些问题。

基本上在我的应用程序中,我有这样的内容

component.html

<ul>
  <li *ngFor="let user of users | filter: filters | order: order | search: searchTerm"></li>
</ul>

component.ts

users = [
  {
    firstName: "Steve", 
    lastName: "Smith", 
    email: "[email protected]", 
    id: 102, 
    tags: [
      'newUser',
      'important',
      'funny'
    ]
  },
  {
    firstName: "James", 
    lastName: "Small", 
    email: "[email protected]", 
    id: 103,
    tags: [
      'important',
      'funny'
    ]
  },
  {
    firstName: "Peter", 
    lastName: "Salvadore", 
    email: "[email protected]", 
    id: 104,
    tags: [
      'newUser',
    ]
  }
];

现在效果很好,但是我知道这不是很有效

现在我的烟斗看起来像这样

filter.pipe.ts

// ...

public transform(value: User, tags: string[]) {
  if (value) {
    if (tags?.length > 0) {
      let users = [];
      tags.forEach(tag => {
        users = [...users, ...value.filter(x => x.tags.includes(tag))];
      });
      return users;
    } else {
      return value;
    }
  }
}

order.pipe.ts

// ...
public transform(value: User, order: string = 'firstName') {
  switch(order) {
    case 'firstName':
     return orderBy(value, ['firstName'], ['asc']);
    // ...
  }
}

等。现在我想移动这些管道并创建函数,但是我的问题是如何正确地链接它们以模仿它们作为链接管道的工作方式。

我想我可以做这样的事情...

private USERS: Users = [ ... ];
public users: Users;
this.users = this.search(this.order(this.filter(this.USERS, filters), order), searchTerm); 

但是那是最好的方法吗?

angular typescript
2个回答
1
投票

每次更改参数之一时,必须执行整个管道链。您可以通过将管道分开来避免这种副作用。

 <ng-container *ngIf="users | filter: filters as filtered">
   <ng-container *ngIf="filtered | order: order as ordered">
      <ng-container *ngIf="ordered | search: searchTerm as searched">
         <li *ngFor="let user of searched"></li>
      </ng-container>
   </ng-container>
 </ng-container>

仅当更改<ng-container>order参数时,才会更新相关的searchTerm。这里唯一的条件是,所有内容都必须产生一个truthy值,*ngIf="xxx as yyy"才能按预期工作。您应该可以接受您的示例。


0
投票

经过一些研究,我想出了以下解决方案

我删除了管道,并创建了一个将所有功能链接在一起并返回所需输出的助手类

sort-users.ts

export class SortUsers {
   private _users: Users[];

   constructor(@Optional() users: Users[]) {
     this._users = users;
   }

   private search() {
     // ...
     return this;
   }

   private filter() {
     // ...
     return this;
   }

   private order() {
     // ...
     return this
   }

   public sort(users, searchTerm, filters, order) {
      const sort = new SortUsers(users);
      return sort
        .search(searchTerm)
        .filter(filters)
        .order(order)
   }
}

然后在我的组件中

private USERS: Users[];
users: Users[]

// ...

constructor(
  private _sort: SortUsers
) {}

// ...

sortUsers() {
   // ...
   this.users = this._sort(this._USERS, this.searchTerm, this.filters, this.order);
}
© www.soinside.com 2019 - 2024. All rights reserved.