【问题标题】:Angular 9 - Cannot use an Observable in an ngFor statementAngular 9 - 不能在 ngFor 语句中使用 Observable
【发布时间】:2021-04-30 16:20:18
【问题描述】:

我有以下函数从 Angular 9 服务返回数据:

@Injectable({
   providedIn: 'root'
})
export class SecurityService {

constructor(private http: HttpClient) { }

public getFunds(): Observable<any> {
  // could do a loader here, or in an interceptor - same for the post, put and delete
  let data = this.http.get<any>("https://localhost:44337/security/").pipe(   
    map(response => response)
  );
return data;

} }

服务按预期返回数据。我这样称呼它:

export class AppComponent {   
funds$!: Observable<any>; // "!" turns off check to make sure vars are initialized, not good tho
constructor(private securityService: SecurityService) {}

ngOnInit() {
    this.funds$ = this.securityService.getFunds();
    this.securityService.getFunds().subscribe(f => (this.funds$ = f));
  }
}

在我的 html 中,我尝试使用这样的数据:

 <tr *ngFor="let f of funds$">
  <td>{{ f.id }}</td>
  <td>{{ f.name }}</td>
  <td>{{ f.assets }}</td>
</tr>

我收到此错误:TS2322:类型“Observable”不可分配给类型“any[] |可迭代 | (可迭代 & 任何[]) | (任何[] & 可迭代) |空 |不明确的'。 类型 'Observable' 不可分配给类型 'any[] & Iterable'。 类型 'Observable' 不可分配给类型 'any[]'。

这在几年前曾经有效。显然 Angular 9 改变了一些东西......

【问题讨论】:

标签: angular


【解决方案1】:

使用异步管道并将模板更改为:-

<ng-container *ngIf="funds$">
    <tr *ngFor="let f of funds$|async">
      <td>{{ f.id }}</td>
      <td>{{ f.name }}</td>
      <td>{{ f.assets }}</td>
    </tr>
</ng-container>

【讨论】:

  • 好吧,我从服务中取回数据,但页面上什么也没有。我在控制台中看到此错误:错误:InvalidPipeArgument: '[object Object],[object Object]' for pipe 'AsyncPipe'。我是否可能需要以某种方式更改服务?无论如何,我现在正在调查错误。谢谢。
  • 服务被调用了两次。第一个返回数据,但第二个不返回。同样的结果,同样的错误。 :(
  • 从 ngoninit 中删除 seconds 语句,即:- this.securityService.getFunds().subscribe(f => (this.funds$ = f));或保留您的原始模板并从 ngoninit 中删除第一条语句。
【解决方案2】:

当我们在 HTML 模板中使用 async pipe 时,我们不必订阅异步管道中引用的 observable。异步管道在幕后为我们订阅它。因此,在组件中,我们只需要构建 observable。

另外,在访问异步管道数据之前,需要确保流可用 *ngIf。

在这些方面,有一些变化 -

在你的组件中 -

export class AppComponent {   
  funds$: Observable<any>;
  constructor(private securityService: SecurityService) {}

  ngOnInit() {
      this.funds$ = this.securityService.getFunds(); // Only this line is enough
  }
}

在您的 HTML 中 -

<ng-container *ngIf="funds$">
    <tr *ngFor="let f of funds$|async">
      <td>{{ f.id }}</td>
      <td>{{ f.name }}</td>
      <td>{{ f.assets }}</td>
    </tr>
</ng-container>

【讨论】:

    【解决方案3】:

    当您订阅 observable 时,它​​通过 getFunds 方法返回,最终返回数据。所以不需要将funds$定义为Observable。下面的代码可能会对您有所帮助。

    funds: any[] = [];
    
    ngOnInit() {
        this.securityService.getFunds().subscribe(f => (this.funds = f));
      }
    }
    

    在 HTML 中使用 ngFor 中的资金变量。

    【讨论】:

    • 它被定义为一个 Observable。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 2021-09-24
    • 2023-03-20
    • 2021-02-04
    • 2020-09-08
    相关资源
    最近更新 更多