angular - ANGULAR - 服务尚未完成加载 Observable在被方法使用之前
问题描述
所以我得到了我的 HomeComponent,它使用 MatTableDataSourceopenFaultsSource$
获取其数据形式,Observable<IFault[]>
以将数据显示为表格。
ngOnInit() {
this.dataProviderService.openFaults$.subscribe(faults => this.openFaultsSource$.data = faults);
this.dataProviderService.closedFaults$.subscribe(faults => this.closedFaultsSource$.data = faults);
}
IFault {
deviceId: number,
locationId: number,
...,
}
我不需要显示 ID,而是显示从其他 Observable 获得的连接名称。例如:
IDevice {
deviceId: number,
deviceName: string,
...,
}
所以我的 HomeComponent.html 看起来像这样:
<table mat-table [dataSource]="openFaultsSource$" class="mat-Table mat-elevation-z8">
<ng-container matColumnDef="deviceName">
<th mat-header-cell *matHeaderCellDef> Gerätenummer </th>
<td mat-cell *matCellDef="let element"> {{getDeviceNameById(element.deviceId) | async}} </td>
</ng-container>
<ng-container matColumnDef="locationName">
<th mat-header-cell *matHeaderCellDef> Örtlichkeit </th>
<td mat-cell *matCellDef="let element"> {{element.locationId}} </td>
</ng-container>
<ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef> Erstellungsdatum </th>
<td mat-cell *matCellDef="let element"> {{element.creationDate}} </td>
</ng-container>
<ng-container matColumnDef="componentName">
<th mat-header-cell *matHeaderCellDef> betroffenes Bauteil </th>
<td mat-cell *matCellDef="let element"> {{element.componentName}}</td>
<td><button mat-button>test</button></td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns" class="table-row" (click) = "openFaultDialog(row)"></tr>
</table>
在 component.ts 中:
getDeviceNameById(id: number): Observable<string> {
return this.dataProviderService.getDeviceNameById(id);
}
我的 dataProviderService 使用所有其他服务,处理逻辑并将数据传递给组件。它看起来像这样:
@Injectable({
providedIn: 'root'
})
export class DataProviderService {
openFaults$: Observable<IFault[]>;
closedFaults$: Observable<IFault[]>;
constructor(private faultLogicService: FaultLogicService,
private deviceLogicService: DeviceLogicService,
private locationLogicService: LocationLogicService,
private componentLogicService: ComponentLogicService,
private deviceTypeLogicService: DeviceTypeLogicService,
private faultTypeLogicService: FaultTypeLogicService,
private solveTypeLogicService: SolveTypeLogicService) {
this.openFaults$ = this.faultLogicService.openFaults$;
this.closedFaults$ = this.faultLogicService.closedFaults$;
}
getComponentsByDeviceName(device: any): any {
throw new Error("Method not implemented.");
}
getDevicesByLocationInput(inputString: any): any {
throw new Error("Method not implemented.");
}
getDeviceNameById(id: number): Observable<string> {
return this.deviceLogicService.getNameById(id);
}
}
现在 deviceLogicService:
@Injectable({
providedIn: 'root'
})
export class DeviceLogicService {
deviceSubject = new BehaviorSubject<IDevice[]>([]);
devices$ = this.deviceSubject.asObservable();
constructor(private deviceService: DeviceService) {
EDIT 1: // this.init(); // init() is called in app.component when calling the
// page for the first time
}
init() {
this.deviceService.getDevices()
.pipe(tap(console.log))
.subscribe(devices => {
this.sortDevices(devices);
this.deviceSubject.next(devices);
});
}
sortDevices(devices: IDevice[]) {
devices.sort((a, b) => a.name.localeCompare(b.name));
}
getNameById(deviceId: number): Observable<string> {
return this.devices$.pipe(map(devices => devices.find(device => device.id === deviceId).name));
}
}
由 deviceLogicService 用来填充其 BS 的 deviceService:
@Injectable({
providedIn: 'root'
})
export class DeviceService {
private accessPointUrl = 'https://localhost:44360/api/Devices/';
constructor(private http: HttpClient) { }
getDevices(): Observable<IDevice[]> {
return this.http.get<IDevice[]>(this.accessPointUrl);
}
}
[问题] 基本上它正在工作,它正在将正确的名称加载到所选的 id,但问题是我收到错误ERROR TypeError: Cannot read property 'name' of undefined
at MapSubscriber.project (device-logic.service.ts:77)
,因为它在服务完成加载所有设备之前调用该方法。
[问题]
有没有办法告诉方法等到所有设备都加载完毕?我的代码结构是否正常,还是很复杂?有没有更简单的方法来获得相同的结果?
我对 Angular 还很陌生,只是不知道如何解决这个问题。我在这里先向您的帮助表示感谢。
解决方案
推荐阅读
- python - PyQT 与 QT Creator
- python - 从包含总分的数组创建“字母成绩”数组
- flutter - 使用 states_rebuilder 注入存储库,在其初始化时执行未来函数并监听更改的最佳方法是什么
- batch-file - 我如何必须转义此批处理代码中的引号?
- asp.net - 有没有办法在 cshtml 页面的 foreach 循环中放置 if 语句?
- reactjs - Draft-js-plugins 表情符号选择组件 - 选择表情符号后关闭弹出框
- ansible - Ansible:在角色执行时应用标签
- ambari - Ambari API + 如何通过 ambari rest api 更改 CPU 调度
- docker - 使用 heroku.yml 构建 Docker 映像时如何指定 --memory
- qt - 如何删除添加到 QChart 的 QGraphicsitem?