Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
239 views
in Technique[技术] by (71.8m points)

typescript - how can i use a function in ngIf condition Angular

i have 2 functions

loadItems(): void {
this.service.query().subscribe((res: HttpResponse<Item[]>) => 
 (this.items = res.body || []));
 }
 
loadAuditByItem(item: Item) {
this.service.auditByItem(item.id!).subscribe((res: HttpResponse<ItemAudit[]>) => 
(this.auditByItem = res.body || []));
 }

i want to display informations from both loadItems() and loadAuditByItem() at the same page i managed to display the name and description from loadItems() but i need to display "createdBy" from loadAuditByItem(item)

<div *ngFor="let item of items">
    <div *ngIf="loadAuditByItem(item)">
        <span>Name: {{ item.name}}</span>
        <span>Description : {{ item.description }}</span>
        <span>Created by: {{ auditByItem .createdBy}}</span>
    </div>
</div>
question from:https://stackoverflow.com/questions/65599506/how-can-i-use-a-function-in-ngif-condition-angular

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Having a function call in ngIf is very bad for performance (you could add a console.log and check your console to see how many times it is been called) instead you could use Pipes, that had been said let me give you a solution for your use case:

import { forkJoin, Observable, of, Subject } from "rxjs";
import { map, switchMap } from "rxjs/operators";
...

  public items$: Observable<Item[]>;

...

  loadItems(): void {
    // please consider to edit your backend API to return all data in one API call
    // since this nested calls will lead to N+1 calls problem.

    this.items$ = this.service.query().pipe(
      map((res: HttpResponse<[]>) => res.body || []),
      switchMap((items: []) => {

        if (items.length === 0) {
          return of([]);
        }

        return forkJoin(
          items.map((item: any) =>
            this.service.auditByItem(item.id).pipe(
              map(audit => {
                item.audit = audit;
                return item;
              })
            )
          )
        );
      })
    );
  }
<div *ngFor="let item of (items$ | async)">
    <div>
        <span>Name: {{ item.name}}</span>
        <span>Description : {{ item.description }}</span>
        <span>Created by: {{ item.audit.createdBy}}</span>
    </div>
</div>

Bonus: It is not good to expose HttpResponse from the service, and it is better to return only the Item[] and encapsulate the HttpResponse there.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...