【问题标题】:Angular 8 using ngIf with async pipe to show and hide the HTML elementAngular 8 使用带有异步管道的 ngIf 来显示和隐藏 HTML 元素
【发布时间】:2020-02-05 17:52:45
【问题描述】:

我正在尝试根据服务结果显示和隐藏 HTML 元素。我正在使用*ngIf="messageService.getData() | async",但它无法显示或隐藏元素。我正在使用异步,否则会在短时间内显示“失败消息”,然后显示“成功消息”。

我有 2 个这样的标签:

<div *ngIf="messageService.getData() | async">Successful Message</div>
<div *ngIf="!messageService.getData() | async">Failure Message</div>

在服务中我有这样的代码:

export class MessageService {
  constructor(private http: HttpClient) { }

  public getData() {
    return this.http.get("https://jsonplaceholder.typicode.com/todos/1")
    .pipe(
      map((response) => {
        console.log("success");
      }),
      catchError(this.handleError)
    )
  }

  private handleError(error: Response) {
    console.log("handleError")
    let errMsg: string;
    errMsg = "error"
    return Observable.throw(errMsg);
  }
}

这里是源代码:https://stackblitz.com/edit/angular-iqr6az

【问题讨论】:

    标签: javascript html angular typescript observable


    【解决方案1】:

    为您服务:

    public getData() {
        return this.http.get("https://jsonplaceholder.typicode.com/todos/1")
        .pipe(
          map((response) => {
            return response; // return res
          }),
          catchError(this.handleError)
        )
      }
    

    在您的组件中:

    export class MessageComponent implements OnInit {
      isServiceAPIWorking: boolean;
      todos;
      loadingError$ = new Subject<boolean>();
      constructor(private messageService: MessageService) { }
    
      ngOnInit() {
        this.todos = this.messageService.getData().pipe(
          catchError((error) => {
            // it's important that we log an error here.
            // Otherwise you won't see an error in the console.
            console.error('error loading the list of users', error);
            this.loadingError$.next(true);
            return of();
          })
        );
      }
    }
    

    在您的 html 中:

    <div>Show Message:</div>
    <div *ngIf="todos | async">Successfull Message</div>
    <div *ngIf="loadingError$ | async">Failure Message</div>
    

    DEMO ??.

    【讨论】:

    • 干得好@Fateme 这是我看到的最好的答案,当我遇到这样的问题时我也会这样做。
    • @FatemeFazli 我正在尝试查看“失败消息”,但它给出了 Observable.throw 不是函数错误。我将其更改为“throwError”,但仍不显示。
    【解决方案2】:

    这是async 管道的错误用法,不是在语法上而是在语义上。每次触发更改检测时,您都在发出 HTTP 请求。

    您可以存储两个标志(布尔变量)或一个用于 HTTP 请求的布尔变量和一个用于响应的变量,而不是使用 async 管道检查。

    下面的例子是使用两个标志。

    export class MessageService {
    
      isLoaded = false;
      hasError  = false;
    
      constructor(private http: HttpClient) { }
    
      public getData() {
        this.isLoaded = false;
        this.http.get("https://jsonplaceholder.typicode.com/todos/1")
        .subscribe(
           (response) => {
               this.hasError = false;
               this.isLoaded = true;
           },
           (error) => {  
               this.hasError = true;
               this.isLoaded = true;
           },
        )
      }
    }
    

    在模板中:

    <ng-container *ngIf="isLoaded">
        <div *ngIf="!hasError">Successfull Message</div>
        <div *ngIf="hasError">Failure Message</div>
    </ng-container>
    

    【讨论】:

    • 我明白你的意思,但如果你不使用异步,“失败消息”会在页面加载时显示一小段时间。
    • 嗯.. 交换isLoadedhasError 的分配有什么效果?更新了答案
    【解决方案3】:

    既然可以在组件中分配数据,为什么还要使用异步管道?

    // message.component.ts
    
    class MessageComponent implements OnInit {
      isServiceAPIWorking: boolean;
      data: any;
      constructor(private messageService: MessageService) { }
    
      ngOnInit() {
        this.messageService.getData()
          .subscribe(response => {
            this.isServiceAPIWorking = true;
            // Assign the data
            this.data = response;
          },
            error => {
              this.isServiceAPIWorking = false;
            })
      }
    }
    
    // message.component.html
    
    <div>Show Message:</div>
    <div *ngIf="data">Successfull Message</div>
    <div *ngIf="!data">Failure Message</div>
    

    您的服务有误。如果你使用map 而不返回任何东西,你最终不会得到任何数据。如果要进行日志记录,请使用 tap

    // message.service.ts
    
    public getData() {
      return this.http.get("https://jsonplaceholder.typicode.com/todos/1")
      .pipe(
        tap((response) => {
          console.log("success");
        }),
        catchError(this.handleError)
      )
    }
    

    Updated Stackblitz

    【讨论】:

    • 如果不使用异步,会短暂显示“Failure Message”,然后显示“Sucess Message”。
    • 是的,当然,我只是调整了你的逻辑,但你可以做更聪明的事情来做你想做的事。
    猜你喜欢
    • 2017-05-11
    • 2021-03-07
    • 1970-01-01
    • 2018-09-10
    • 2019-06-12
    • 2019-10-01
    • 1970-01-01
    • 2016-05-11
    • 2021-06-09
    相关资源
    最近更新 更多