Apollo-Angular+PrimeNG DataView类型不匹配错误修复求助
Apollo-Angular + PrimeNG DataView 类型不匹配问题解决
问题描述
我尝试使用搭配codegen的Apollo-Angular从服务器请求数据,并在PrimeNG的DataView组件中展示数据,但出现TS2740类型不匹配错误:Observable数组缺少any[]的length、pop等属性。疑惑是否需要使用PrimeNG文档中提及的接口,若需要该如何实现?
相关代码
blueprints-list.component.ts
import { Component, OnInit } from '@angular/core'; import { QueryRef } from 'apollo-angular'; import { BlueprintsGQL, BlueprintsQuery } from 'from-ui-to-api'; import { PrimeNGConfig, SelectItem } from 'primeng/api'; import { map, Observable } from 'rxjs'; import { BlueprintService } from './services/blueprint.service'; @Component({ selector: 'printi-price-blueprints-list', templateUrl: './blueprints-list.component.html', styleUrls: ['./blueprints-list.component.scss'], }) export class BlueprintsListComponent implements OnInit { blueprints$!: Observable<BlueprintsQuery['Blueprints']>; queryRef!: QueryRef<BlueprintsQuery>; sortOptions!: SelectItem; sortOrder!: number; sortField!: string; constructor( private blueprintService: BlueprintService, private primengConfig: PrimeNGConfig, private getBlueprintsGQL: BlueprintsGQL ) {} ngOnInit(): void { this.blueprints = this.getBlueprintsGQL.watch().valueChanges.pipe( map(result => result.data.Blueprints) ); } }
blueprints-list.component.html
<div class="card"> <p-dataView #dv [value]="blueprints" [paginator]="true" [rows]="9" filterBy="name" [sortField]="sortField" [sortOrder]="sortOrder" layout="grid" >
报错信息
Error: libs/catalog/blueprints/ui/src/lib/blueprints-list/blueprints-list.component.html:4:6 - error TS2740: Type 'Observable<{ __typename?: "Blueprint" | undefined; id: string; ID?: number | null | undefined; title: string; brand: string; model?: string | null | undefined; description: string; }[]>' is missing the following properties from type 'any[]': length, pop, push, concat, and 28 more. 4 [value]="blueprints" ~~~~~ libs/blueprints-list/blueprints-list.component.ts:10:16 10 templateUrl: './blueprints-list.component.html', ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Error occurs in the template of component BlueprintsListComponent.
解决方法
核心原因
PrimeNG DataView的[value]属性需要接收普通数组,但你传递的是Observable对象,Angular模板不会自动订阅Observable,因此出现类型不匹配。
步骤1:修正组件变量赋值
你组件中定义的变量是blueprints$,但ngOnInit里错误赋值给了this.blueprints,先修正变量名匹配:
ngOnInit(): void { this.blueprints$ = this.getBlueprintsGQL.watch().valueChanges.pipe( map(result => result.data.Blueprints) ); }
步骤2:用async管道处理Observable
在模板中通过async管道订阅Observable,将发射出的数组传递给DataView:
<div class="card"> <p-dataView #dv [value]="blueprints$ | async" [paginator]="true" [rows]="9" filterBy="title" <!-- 注意:你的数据结构里是title字段,不是name,这里要对应 --> [sortField]="sortField" [sortOrder]="sortOrder" layout="grid" >
关于PrimeNG接口的疑问
不需要额外实现PrimeNG特定接口,只要你的数据结构和DataView的配置匹配即可(比如filterBy指定的字段要存在于数据对象中)。codegen已经为你生成了BlueprintsQuery['Blueprints']类型,直接使用就足够严谨。
额外优化:处理加载状态
可以结合*ngIf和async管道添加加载状态提示:
<div class="card"> <ng-container *ngIf="blueprints$ | async as blueprints; else loading"> <p-dataView #dv [value]="blueprints" [paginator]="true" [rows]="9" filterBy="title" [sortField]="sortField" [sortOrder]="sortOrder" layout="grid" > <!-- DataView的内容模板 --> </p-dataView> </ng-container> <ng-template #loading> <p>数据加载中...</p> </ng-template> </div>
内容的提问来源于stack exchange,提问作者Satyadev
相关产品推荐
相关产品推荐

