*NgFor 不显示数据
*NgFor does not display the data
我正在编写我的第一个 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;
}
}
银行-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();
}
}
如果有人能解释一下,我将不胜感激,我似乎无法理解我的错误。
提前致谢
那是因为异步函数正在获取数据,但您试图在获取数据之前显示它,因此,您正在遍历一个空数组。您可以通过不初始化数组(将 bankAccounts: any[] = [];
更改为 bankAccounts: any[];
)并用 <div *ngIf="bankAccounts"></div>
围绕您的 <ul>
标签轻松解决此问题。这样,bankAccounts
数组在获取数据之前将是未定义的,并且由于 *ngIf
指令,您的 *ngFor
循环将在填充数组后立即执行。
您的代码不起作用,因为该服务异步填充其 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 发出后自动显示数据。
我正在编写我的第一个 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;
}
}
银行-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();
}
}
如果有人能解释一下,我将不胜感激,我似乎无法理解我的错误。
提前致谢
那是因为异步函数正在获取数据,但您试图在获取数据之前显示它,因此,您正在遍历一个空数组。您可以通过不初始化数组(将 bankAccounts: any[] = [];
更改为 bankAccounts: any[];
)并用 <div *ngIf="bankAccounts"></div>
围绕您的 <ul>
标签轻松解决此问题。这样,bankAccounts
数组在获取数据之前将是未定义的,并且由于 *ngIf
指令,您的 *ngFor
循环将在填充数组后立即执行。
您的代码不起作用,因为该服务异步填充其 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 发出后自动显示数据。