* ng如果HTTP请求完成后条件没有更新?

时间:2018-10-29 13:14:52

标签: angular typescript

我有一个按钮,当用户单击该按钮时,它会调用GitLab API并呈现获取的数据。不幸的是,我需要单击两次按钮以显示数据。第一次单击时,它不会显示任何内容。

这是HTML模板代码:

<div *ngIf="!afterLogIn">
  <button (click)="apiData()">Gitlab project</button>
</div>

<div class="content" *ngIf="afterLogIn" >

  <div *ngFor="let data of api">
    <div class="item">
      <div class="flag"></div>
      <div class="description">
        <div class="title styles-pro-medium-bold">
          {{ data.name }}
        </div>
        <div class="about styles-pro-small">
          {{ data.description}}
        </div>
      </div>
      <div class="more styles-pro-header">
        <div class="more">
          ...
        </div>
      </div>
    </div>
  </div>
</div>

我的component.ts文件:

constructor(
    private router: Router,
    private store$: Store<RootStoreState.State>,
    private gitLabApi: GitLabApiService
  ) {}   
apiData() {
        this.gitLabApi.getApi().subscribe(apiData => {
          this.api = apiData;
          console.log(this.api);  // first click showed the data in console

        this.afterLogIn = true;
        });
       }

这是我正在使用的服务:

export class GitLabApiService {
    url ='https://gitlab.com/api/v4/projects?access_token=sometoken&owned=true&simple=true';
      constructor(private http: HttpClient) {}

      getApi(): Observable<any> {
        return this.http.get<any>(this.url);
      }
}

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

问题是未触发更改检测。如果您想继续使用OnPush,则需要稍微调整一下代码:

constructor(
  private router: Router,
  private store$: Store<RootStoreState.State>,
  private gitLabApi: GitLabApiService,
  private cd: ChangeDetectorRef  // add this line
) {} 

apiData() {
  this.gitLabApi.getApi().subscribe(apiData => {
     this.api = apiData;
     this.afterLogIn = true;
     this.cd.markForCheck() // add this line
  });
}

或者,您甚至可以像这样使用async管道:

<div class="content" *ngIf="afterLogIn">
  <div *ngFor="let data of api | async">
  //...

并将代码更改为:

apiData() {
  this.api = this.gitLabApi.getApi().pipe(
    tap(() => this.afterLogIn = true)
  );
}