Angular传递数据时出现Property 'id'不存在于类型'{}'错误
解决Angular中BehaviorSubject订阅时"Property 'id' does not exist on type '{}'"错误
问题根源
错误产生的核心原因是BehaviorSubject初始化时传入了空对象{},TypeScript自动推断其类型为{},导致订阅时访问data.id触发类型检查错误。同时BehaviorSubject会在订阅时立即发送初始值,这就是你console.log(data)得到空对象的原因。
解决步骤
1. 定义明确的状态类型
先创建一个接口规范传递的状态数据结构,替换匿名类型:
// 可放在service文件或单独的types文件中 export interface AccordionState { id: string; state: boolean; }
2. 修改Service中的BehaviorSubject配置
给BehaviorSubject指定明确类型,并设置符合该类型的初始值,而非空对象:
import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; import { AccordionState } from './your-path-to-types'; // 替换为实际文件路径 @Injectable({ providedIn: 'root' }) export class SidePanelAccordianService { // 指定类型并设置合法初始值 private _openStateBehaviorSubject = new BehaviorSubject<AccordionState>({ id: '', state: false }); public openState$ = this._openStateBehaviorSubject.asObservable(); public setOpenState(data: AccordionState) { this._openStateBehaviorSubject.next(data); } }
3. 优化订阅逻辑(可选)
类型明确后已不会有类型错误,若想规避初始默认值的影响,可在订阅时过滤无效初始值:
import { filter } from 'rxjs/operators'; // ... this.accordianStateService.openState$ .pipe(filter(data => data.id !== '')) // 过滤掉初始空id值 .subscribe(data => { if (data.id === 'firstAccordionId') { this.firstDriverExpanded = true; } else if (data.id === 'secondAccordionId') { this.secondDriverExpanded = false; this.thirdDriverExpanded = false; // 合并原代码中重复的判断逻辑 } });
额外修正:HTML模板绑定错误
你的模板中mat-expansion-panel的(id)是错误的事件绑定写法,应改为属性绑定[id],同时修正opened/closed事件的赋值逻辑:
<mat-accordion> <mat-expansion-panel [id]="data.id" (opened)="data.panelOpenState = true" (closed)="data.panelOpenState = false" [expanded]="data.expanded" (click)="stateValue()"> <mat-expansion-panel-header> <mat-panel-title> {{ data?.title }} </mat-panel-title> </mat-expansion-panel-header> <ng-content></ng-content> </mat-expansion-panel> </mat-accordion>
内容的提问来源于stack exchange,提问作者RRB
相关产品推荐
相关产品推荐

