ngrx中getWithQuery()设置默认参数后无参调用报错如何解决
问题原因
- NgRx 原生
DefaultDataService的getWithQuery方法签名要求至少传入1个查询参数,同时还支持第二个可选的Http配置参数,你在子类重写方法时没有保留第二个可选参数,导致方法签名和父类不匹配,类型校验依然按照父类签名校验,要求传入1-2个参数。 - 你调用方法的载体是
companyEntityService,EntityService的接口声明默认没有无参调用的重载,即使DataService层加了参数默认值,上层EntityService的类型校验也会报错。 - 若未将自定义的
CompaniesDataService注册绑定到Company实体,NgRx Data会走默认的DefaultDataService实现,你写的自定义方法完全不会生效。
解决方案
步骤1:修正自定义DataService的方法签名
补全父类方法的第二个可选参数,保证方法签名匹配:
import { HttpOptions } from '@ngrx/data/src/dataservices/interfaces'; @Injectable({providedIn: 'root'}) export class CompaniesDataService extends DefaultDataService<Company> { private readonly _URL: string = '/api/companies'; private readonly _DEFAULT_QUERIES: QueryParams = {top: '0', limit: '10', order: "name"}; constructor(http: HttpClient, httpUrlGenerator: HttpUrlGenerator) { super('Company', http, httpUrlGenerator); } // 补全第二个可选参数options,匹配父类签名 getWithQuery(queryParams: QueryParams | string = this._DEFAULT_QUERIES, options?: HttpOptions): Observable<Company[]> { return this.http .post<FmsHttpResponse<Company>>(`${this._URL}/search`, queryParams, options) .pipe(map(response => response.content)); } }
步骤2:注册自定义DataService到NgRx Data
在根模块/特性模块中完成自定义DataService和实体的绑定,确保你的自定义实现生效:
import { NgModule } from '@angular/core'; import { EntityDataModule, EntityDataService } from '@ngrx/data'; import { CompaniesDataService } from './companies-data.service'; // 引入你的实体配置 @NgModule({ imports: [ // 其他模块导入 EntityDataModule.forRoot(/* 你的NgRx Data实体配置 */) ], providers: [CompaniesDataService] }) export class AppModule { constructor( entityDataService: EntityDataService, companiesDataService: CompaniesDataService ) { // 绑定自定义服务到Company实体 entityDataService.registerService('Company', companiesDataService); } }
步骤3:添加无参调用的类型支持(二选一即可)
方案A:自定义EntityService(推荐,保留类型校验)
自定义CompanyEntityService,重载getWithQuery方法支持无参调用:
import { Injectable } from '@angular/core'; import { EntityCollectionServiceBase, EntityCollectionServiceElementsFactory, QueryParams } from '@ngrx/data'; import { Company } from './company.model'; @Injectable({ providedIn: 'root' }) export class CompanyEntityService extends EntityCollectionServiceBase<Company> { private readonly _DEFAULT_QUERIES: QueryParams = {top: '0', limit: '10', order: "name"}; constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) { super('Company', serviceElementsFactory); } // 重载方法,支持无参调用 override getWithQuery(queryParams?: QueryParams | string, options?: any) { return super.getWithQuery(queryParams ?? this._DEFAULT_QUERIES, options); } }
之后在resolver中注入该自定义CompanyEntityService,即可正常无参调用getWithQuery()。
方案B:临时忽略类型校验(不推荐)
如果只是临时调试,可以在调用处添加注释忽略类型报错:
// @ts-ignore return this.companyEntityService.getWithQuery() .pipe(tap(() => this.companyEntityService.setLoaded(true)));
内容的提问来源于stack exchange,提问作者Ania
相关产品推荐
相关产品推荐

