标签内容出现性能问题

时间:2019-06-03 21:21:25

标签: angular typescript ngfor

我正在尝试使用ngfor和ngif制作三个标签。 它实际上可以正常工作,但是存在性能问题 看代码

<mat-nav-list class="op-content">
  <h5>Listar Usuários</h5>
  <input matInput [(ngModel)]="searchText" placeholder="Filtrar por nome" class="filter-input">
  <mat-tab-group>

    <mat-tab label="Todos" [(ngModel)]="searchText" name="todos" ngDefaultControl>
      <ng-container *ngFor="let op of tboperadores | filter : searchText">
        <mat-list-item>
          <a matLine [routerLink]="['/operadores', op.id_operador]">
            <span class="badge badge-primary"> {{op.id_operador}}</span>
            Nome: {{ op.nome }} CPF: {{ op.identificacao }}</a>
        </mat-list-item>
      </ng-container>
    </mat-tab>

    <mat-tab label="Habilitados" [(ngModel)]="searchText" name="habilitado" ngDefaultControl>
      <ng-container *ngFor="let op of tboperadores | filter : searchText">
        <ng-container *ngIf="op.habilitado =='S'">
          <mat-list-item>
            <a matLine [routerLink]="['/operadores', op.id_operador]">
              <span class="badge badge-primary"> {{op.id_operador}}</span>
              Nome: {{ op.nome }} CPF: {{ op.identificacao }}</a>
          </mat-list-item>
        </ng-container>
      </ng-container>
    </mat-tab>

    <mat-tab label="Desabilitados" [(ngModel)]="searchText" name="desabilitado" ngDefaultControl>
      <ng-container *ngFor="let op of tboperadores | filter : searchText">
        <ng-container *ngIf="op.habilitado=='N'">
          <mat-list-item>
            <a matLine [routerLink]="['/operadores', op.id_operador]">
              <span class="badge badge-primary"> {{op.id_operador}}</span>
              Nome: {{ op.nome }} CPF: {{ op.identificacao }}</a>
          </mat-list-item>
        </ng-container>
      </ng-container>
    </mat-tab>
  </mat-tab-group>
</mat-nav-list>
<div class="loader" *ngIf="!subscription?.closed" #loading>
</div>

如您所见,每次打开新选项卡时,我都有一个ngfor。 我试图在整个页面上只放一个, 但我无法使其正常工作。

有人有意识形态如何解决?

编辑:

我的operador.component.ts

import { Component, OnInit, } from '@angular/core';
import { Operador } from './operador';
import { OperadorService } from './operador.service';
import { Subscription, Observable } from 'rxjs';


@Component({
  selector: 'app-operador',
  templateUrl: './operador.component.html',
  styleUrls: ['./operador.component.css']
})
//export class OperadorComponent implements OnInit, PipeTransform {
export class OperadorComponent implements OnInit {
  tboperadores: Operador[];
  checkedOperadors: Operador[];

  subscription: Subscription;
  mode = 'indeterminate';

  constructor(private operadorService: OperadorService) {
  }

  ngOnInit(): void {
    this.subscription = this.getOperadores();
  }

  getOperadores() {

    return this.operadorService.getOperadores()
      .subscribe(ob => {
        console.log(ob);
        this.tboperadores = ob;
      });

  }
}

然后,我的filter.pipe.ts:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
  transform(items: any[], searchText: string): any[] {
    if(!items) return [];
    if(!searchText) return items;
searchText = searchText.toLowerCase();
return items.filter( it => {
      return it.nome.toLowerCase().includes(searchText);
    });
   }
}

  • 我的operador.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Operador } from './operador';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class OperadorService {
  private operadoresUrl = '******';  // URL to web api
  constructor( 
    private http: HttpClient
  ) { }

  getOperadores (): Observable<Operador[]> {
    return this.http.get<Operador[]>(this.operadoresUrl)
  }

  getOperador(id_operador: number): Observable<Operador> {
    const url = `${this.operadoresUrl}/${id_operador}`;
    return this.http.get<Operador>(url);
  }

  addOperador (operador: Operador): Observable<Operador> {
    return this.http.post<Operador>(this.operadoresUrl, operador, httpOptions);
  }

  deleteOperador (operador: Operador | number): Observable<Operador> {
    const id_operador = typeof operador === 'number' ? operador : operador.id_operador;
    const url = `${this.operadoresUrl}/${id_operador}`;

    return this.http.delete<Operador>(url, httpOptions);
  }

  updateOperador (operador: Operador): Observable<any> {
    return this.http.put(this.operadoresUrl, operador, httpOptions);
  }
}

EDIT2:

我已经编辑了此方法以进行过滤:

  getOperadores(option): Observable<Operador[]> {
    if (option == 0) {
      return this.http.get<Operador[]>(this.operadoresUrl)
    } else if (option == 1) {
      return this.http.get<Operador[]>(this.operadoresUrl).pipe(
        map((reports: Operador[]) => reports.filter(p => p.habilitado === "S"))
      );
    } else {
      return this.http.get<Operador[]>(this.operadoresUrl).pipe(
        map((reports: Operador[]) => reports.filter(p => p.habilitado === "N"))
      );

    }
  }

并创建了这两个方法来调用构造函数:

  checkedOperadores() {

    return this.operadorService.getOperadores(1)   
    .subscribe(  ob  =>  {
       console.log(ob);
       this.checkedOperadors = ob;
      });

  }

  uncheckedOperadores() {

    return this.operadorService.getOperadores(2)   
    .subscribe(  ob  =>  {
       console.log(ob);
       this.uncheckedOperadors = ob;
      });

  }

但是性能问题仍然存在...

1 个答案:

答案 0 :(得分:2)

从文档中,您可以使用延迟加载来增强初始化阶段:

https://material.angular.io/components/tabs/overview#lazy-loading

  

延迟加载
  默认情况下,选项卡的内容会急切加载。热切地   加载的选项卡将激活子组件,但不会注入它们   进入DOM,直到选项卡被激活。

     

如果选项卡包含多个复杂的子组件或选项卡的   建议内容在初始化期间依赖DOM计算   延迟加载选项卡的内容。

     

可以通过在ng-template中声明主体来延迟加载Tab内容   带有matTabContent属性。

如果仍然存在性能问题,则必须弄清楚如何在for循环上使用虚拟滚动。

更新
我不知道您的过滤器管道是如何实现的,但是无论是纯管道还是不纯管道,您都必须注意。与https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe相关的问题可能会导致性能问题。

您也可以改善代码:

1-创建三个get方法,每个方法用于一种habilitado,例如:

get habilitados() {
   return tboperadores.filter(op => op.habilitado === 'S')
}

然后在ngFor中使用它并获得ngIf。

2-也许为下面的代码创建一个组件以减少代码行:

<mat-list-item>
   <a matLine [routerLink]="['/operadores', op.id_operador]">
      <span class="badge badge-primary"> {{op.id_operador}}</span>
        Nome: {{ op.nome }} CPF: {{ op.identificacao }}
   </a>
</mat-list-item>