NgRx Data自定义Data Service未触发后端接口请求问题
NgRx Data 点击按钮不触发后端接口请求问题
问题场景
在示例项目中搭建NgRx Data环境,目标是通过Data Service获取Employee实体数据并存储到状态中。按如下方式定义数据服务、集合服务与AppModule,同时在首页添加All Employees按钮用于拉取数据库全部员工数据,但点击按钮时对应后端接口始终未被调用,排查为基础配置遗漏。
现有代码实现
all-employees.component.html
<h1>All Employees</h1> <ul> <li *ngFor="let employee of employees$ | async">{{ employee.lastName }}, {{ employee.firstName }}</li> </ul>
employee-data.service.ts
@Injectable() export class EmployeeDataService extends DefaultDataService<Employee> { constructor(http: HttpClient, httpUrlGenerator: HttpUrlGenerator, logger: Logger) { super('Employee', http, httpUrlGenerator); logger.log('Created custom Employee EntityDataService'); } override getAll(): Observable<Employee[]> { return this.http.get<Employee[]>('http://localhost:3000/employees'); } }
employee.service.ts(员工集合服务)
@Injectable({ providedIn: 'root', }) export class EmployeeService extends EntityCollectionServiceBase<Employee> { constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) { super('Employee', serviceElementsFactory); } }
app.module.ts(根模块配置)
@NgModule({ declarations: [AppComponent], imports: [ BrowserModule, HttpClientModule, RouterModule.forRoot( [ { path: 'all_employees', component: AllEmployeesComponent, }, ], { initialNavigation: 'enabledBlocking' } ), StoreModule.forRoot(reducers, { metaReducers: !environment.production ? [] : [], runtimeChecks: { strictActionImmutability: true, strictStateImmutability: true, }, }), EntityDataModule.forRoot({ entityMetadata: appEntityMetadata, }), EffectsModule.forRoot([]), !environment.production ? StoreDevtoolsModule.instrument() : [], StoreRouterConnectingModule.forRoot(), ], providers: [EmployeeDataService], bootstrap: [AppComponent], }) export class AppModule { constructor(entityDataService: EntityDataService, EmployeeDataService: EmployeeDataService) { entityDataService.registerService('Employee', EmployeeDataService); } }
复现步骤
- 克隆仓库并安装依赖
- 启动示例JSON server
json-server --watch db.json
- 运行项目
nx serve ngrx-demo
问题根因与修复方案
核心遗漏点有3个,按优先级排查修复即可:
- 未显式调用数据拉取方法
employees$ | async仅会订阅状态流,不会自动触发接口请求。必须在组件中显式调用集合服务的getAll()方法,才会派发对应action、触发自定义DataService的请求逻辑。
正确的组件类写法示例:
@Component({ selector: 'app-all-employees', templateUrl: './all-employees.component.html' }) export class AllEmployeesComponent implements OnInit { // 直接绑定集合服务的实体流 employees$ = this.employeeService.entities$; constructor(private employeeService: EmployeeService) {} ngOnInit(): void { // 如果需要进入页面就拉取数据,在初始化钩子中调用 this.employeeService.getAll(); } // 如果是点击按钮触发拉取,将该方法绑定到按钮的click事件上 onLoadEmployeesClick() { this.employeeService.getAll(); } }
- 实体元数据未正确注册
检查appEntityMetadata配置中是否存在Employee实体的定义,实体名称必须和服务中传入的'Employee'字符串完全一致(大小写敏感),否则NgRx Data不会为该实体创建对应的状态切片、处理对应action。 - 依赖注入参数命名歧义
AppModule构造函数中注册自定义服务时,参数名和类名EmployeeDataService完全重名,容易引发依赖注入解析异常,将参数名改为小写开头即可:
export class AppModule { constructor(entityDataService: EntityDataService, employeeDataService: EmployeeDataService) { entityDataService.registerService('Employee', employeeDataService); } }
内容的提问来源于stack exchange,提问作者Pavan Jadda
相关产品推荐
相关产品推荐

