简体   繁体   English

Angular,使用ngIf,异步和Observable等麻烦,等到数据准备好显示内容

[英]Angular, trouble using ngIf, async and Observable to wait until data is ready to display content

I am new to Angular and I am stuck. 我是Angular的新手,但我陷入困境。 I can't seem to get this to work and I think I'm just making some mistakes on how I'm implementing the Observable. 我似乎无法使它正常工作,我认为我在实现Observable的方式上犯了一些错误。 Currently I am using a local json file as my data source, but in my main project I will connect to an external API. 目前,我正在使用本地json文件作为数据源,但是在我的主项目中,我将连接到外部API。 I have stripped everything down to make it as basic as possible and still no luck. 我已经精简了所有内容,使其尽可能基本,但仍然没有运气。

Here's campaign.component.ts 这是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);
        });
      }
    }

Here's the template html, campaign.component.html 这是模板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>

Here's the service, campaign.service.ts 这是服务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));
      }

    }

Thanks for taking the time to help with this. 感谢您抽出宝贵的时间来帮助您。

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

The above assigns the data value to the property this.$campaign but you've declared that property to be an observable. 上面将数据值分配给属性this.$campaign但您已将该属性声明为可观察的。

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

$campaign is not an observable so the async pipe resolves to undefined. $ campaign不是可观察到的,因此异步管道解析为undefined。 The condition is always 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>

The above works because $campaign was assigned the data value. 上面的工作是因为$ campaign被分配了数据值。

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

You should always use async in the template for observables. 您应该始终在模板中使用async进行观察。

You can simplify the component by assigning the observable in the constructor. 您可以通过在构造函数中分配observable来简化组件。

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

Alternatively, you don't have to use async if you subscribe and assign the data. 另外,如果您订阅并分配数据,则不必使用async

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM