【问题标题】:*NgFor does not display the data*NgFor 不显示数据
【发布时间】:2017-01-06 17:40:39
【问题描述】:

我正在编写我的第一个 Angular2 应用程序。

我有一个BankAccountService,它从我的后端服务器获取数据,还有一个bank-account.component,它使用这个服务来简单地显示一个未排序的帐号列表。

通过 chrome devtool 进行调试,我能够看到数据被正确提取并存储在 bankAccounts 数据成员中,但由于某种原因,ul 没有显示任何内容。

银行账户服务:

import { Injectable } from '@angular/core';
import {client} from '../app.module';
import gql from 'graphql-tag';
import {ObservableQuery} from "apollo-client";

@Injectable()
export class BankAccountService{
    bankAccounts: any[] = [];

    constructor() {
        this.queryBankAccounts();
    }

    queryBankAccounts(): any{
        let queryObservable: ObservableQuery = client.watchQuery({
            query: gql`
              {
                bankAccounts {
                  id
                  accountNumber
                  userOwners{
                    firstName
                  }
                 bankId
                  branchId
                  transactions{
                    amount
                    payerId
                    recipientId
                  }
                }
              }
            `,
            pollInterval: 50
        });

        let subscription = queryObservable.subscribe({
            next: ({ data }) => {
                this.bankAccounts = data;
            },
            error: (error) => {
                console.log('there was an error sending the query', error);
            }
        });
    }

    getBankAccounts(){
        return this.bankAccounts;
    }
}

bank-account.component:

import {Component} from "@angular/core";
import {BankAccountService} from "../services/BankAccountService";

@Component({
    selector: 'bank-account',
    template: `<ul>
                    <li *ngFor="let account of bankAccounts">
                        {{account.accountNumber}}
                    </li>
               </ul>`,
    providers: [BankAccountService]
})
export class BankAccountComponent{
    bankAccounts: any[] = [];

    constructor(bankAccountService: BankAccountService){
        this.bankAccounts = bankAccountService.getBankAccounts();
    }
}

如果有人能提供一些启发,我将不胜感激,我似乎无法理解我的错误。

提前致谢

【问题讨论】:

  • 使用ngOnInit方法调用bankAccountService.getBankAccounts()
  • 感谢您的快速回复,我尝试了您的建议,现在看起来数组为空

标签: angular httprequest graphql ngfor


【解决方案1】:

您的代码不起作用,因为服务异步填充其 bankAccounts 数据(当它从服务器获取结果时),而您的组件尝试同步读取数据。在组件读取数据时,服务仍在等待该数据从后端到达。

更好的设计是让服务的getBankAccounts() 成为一个 Observable,当它准备好时会发出数据。然后,您的组件将订阅此服务,并且仅在数据到达后才初始化视图。

服务

//make this observable into a class property
queryObservable:ObservableQuery = client.watchQuery({
    ...
});

//return the observable that will emit the data
getBankAccounts():Observable<any[]>{
    return this.queryObservable;
}

组件

//don't set it to anything, so the *ngIf will work in the template 
bankAccounts: any[];

//better to do this here than in the constructor
ngOnInit(){
    this.bankAccountService.getAccounts().subscribe(
        data => this.bankAccounts = data
    )
}

模板

<!-- only show the list IF the data is available -->
<ul *ngIf="bankAccounts">
    <li *ngFor="let account of bankAccounts">
        {{account.accountNumber}}
    </li>
</ul>

我在这里不赘述,但另一种选择(如果您不想使用*ngIf)是按照我描述的方式离开服务,然后在组件集bankAccounts = service.getBankAccounts() 和模板中使用 async 管道,它需要一个 Observable,并且一旦 Observable 发出就会自动显示数据。

【讨论】:

    【解决方案2】:

    这是因为异步函数正在获取数据,但您试图在获取数据之前显示它,因此,您正在遍历一个空数组。您可以通过不初始化数组(将bankAccounts: any[] = []; 更改为bankAccounts: any[];)并用&lt;div *ngIf="bankAccounts"&gt;&lt;/div&gt; 包围您的&lt;ul&gt; 标记来轻松解决此问题。这样,bankAccounts 数组将在获取数据之前未定义,并且由于 *ngIf 指令,您的 *ngFor 循环将在数组填充后立即执行。

    【讨论】:

    • 感谢您的回复,看来您是对的,对于这种类型的东西,是否有更清洁的方法或任何最佳实践?放置*ngIf 似乎有点脏
    • 实际上,在尝试了您的建议后,它看起来并没有解决它,我用&lt;div *ngIf="bankAccounts"&gt; 包围了&lt;ul&gt;,它仍然是空的.. 有没有办法调试角度 ngForngIf 等部分的 DOM?
    • 我确认 *ngFor 循环只有在它使用的数组不为空时才被执行。
    猜你喜欢
    • 2019-09-18
    • 2019-09-14
    • 1970-01-01
    • 2019-09-30
    • 2017-11-25
    • 2020-09-02
    • 2021-06-28
    • 2017-08-07
    相关资源
    最近更新 更多