【问题标题】:Angular, trouble using ngIf, async and Observable to wait until data is ready to display contentAngular,使用 ngIf、异步和 Observable 等到数据准备好显示内容时遇到问题
【发布时间】:2018-10-10 13:30:27
【问题描述】:

我是 Angular 的新手,我被困住了。我似乎无法让它工作,我认为我只是在如何实现 Observable 方面犯了一些错误。目前我使用本地 json 文件作为我的数据源,但在我的主项目中,我将连接到外部 API。我已经把所有东西都去掉了,让它尽可能基本,但仍然没有运气。

这里是campaign.component.ts

    import { Component, OnInit } from '@angular/core';

    import { Observable } from 'rxjs';

    import { CampaignService } from '../campaign.service';

    @Component({
      selector: 'app-campaign',
      templateUrl: './campaign.component.html',
      styleUrls: ['./campaign.component.css']
    })
    export class CampaignComponent implements OnInit {

    $campaign: Observable<any>;

      constructor(
        private campaignService: CampaignService
      ) {}

      ngOnInit(): void {
        this.getCampaign();
      }

      getCampaign(): void {
        this.campaignService.getCampaign().subscribe((data) => {
          this.$campaign = data;
          console.log(this.$campaign);
        });
      }
    }

这是模板 html,campaign.component.html

    <div *ngIf="($campaign | async) as campaign; else loading">
    <!--this never loads-->
      {{campaign.shortName}}
    </div>

    <ng-template #loading>
    <!--this is all I see-->
      Loading stuff in ngIf...
    </ng-template>

    <br>
    <br>
    <!--this works so I know the data loads and that my json file is formatted correctly-->
    <p>Outside of ngIf works: {{$campaign.shortName}}</p>

这是服务,campaign.service.ts

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
    import { Observable, of } from 'rxjs';
    import { map} from 'rxjs/operators';

    const endpoint = 'assets/api.json';

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

    @Injectable()
    export class CampaignService {

      constructor(private http: HttpClient) {}

      private extractData(res: Response) {
        let body = res;
        return body || { };
      }

      getCampaign(): Observable<any> {
        const url = endpoint;
        console.log(url);
        return this.http.get(url).pipe(
          map(this.extractData));
      }

    }

感谢您抽出宝贵时间提供帮助。

【问题讨论】:

  • 欢迎来到stackoverflow。您的问题包含与可观察对象和异步管道相关的几个问题,并且很难提供一个正确的答案。我唯一能想到的就是为您提供有关如何使用异步管道的教程。 alligator.io/angular/async-pipe

标签: json angular observable angular6


【解决方案1】:
  getCampaign(): void {
    this.campaignService.getCampaign().subscribe((data) => {
      this.$campaign = data;
      console.log(this.$campaign);
    });
  }

上面将数据值分配给属性this.$campaign,但您已将该属性声明为可观察的。

<div *ngIf="($campaign | async) as campaign; else loading">
<!--this never loads-->
  {{campaign.shortName}}
</div>

$campaign 不是可观察的,因此异步管道解析为未定义。条件总是false

<!--this works so I know the data loads and that my json file is formatted correctly-->
<p>Outside of ngIf works: {{$campaign.shortName}}</p>

上述方法有效,因为 $campaign 被分配了数据值。

<p>Outside of ngIf works: {{($campaign | async)?.shortName}}</p>

您应该始终在可观察对象的模板中使用async

您可以通过在构造函数中分配 observable 来简化组件。

  constructor(private campaignService: CampaignService) {
      this.$campaign = campaignService.getCampaign(); 
  }

或者,如果您订阅和分配数据,则不必使用async

<div *ngIf="campaign; else loading">
<!--this never loads-->
  {{campaign.shortName}}
</div>

<p>Outside of ngIf works: {{campaign?.shortName}}</p>

【讨论】:

  • 你可以在这里找到修改后的版本 - stackblitz.com/edit/angular-eyceq1
  • @cgTag,我选择使用您的替代建议,即完全删除 async,一切正常。
  • @C.Lightner 如果这解决了你的问题,那么你能接受答案吗。
猜你喜欢
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-05-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2017-05-14
  • 2016-12-13
相关资源
最近更新 更多