我目前正在尝试使用秋田县在Angular 8中建立一个简单的表单。在继续之前,我必须告诉您我不是开发人员,并且对Angular世界还很陌生……甚至不提及状态管理概念。阅读我的代码时请记住这一点:)
这里是我要实现的目标的简短描述。用户在输入中输入注册号的前几个字符。在下面的自动完成中,建议了数据库中已知的注册号。当用户选择这些值之一时,将使用相应的ID触发服务,并获取所选车辆(在这种情况下为飞机)的数据。返回的数据显示在选择框下方。
到目前为止,很好...我的自动填充框运行良好,商店(显然)已按预期装满。我使用Redux devtools在商店中看到了正确的数据。
当我尝试显示数据时,我的问题就出现了……我可以在页面上用{{ store_aircraft$ | json }}
之类的东西看到商店中的整个对象,这给了我类似的东西:
{
"_isScalar": false,
"source": {
"_isScalar": false,
"source": {
"_isScalar": false,
"source": {
"_isScalar": false,
"source": {
"_isScalar": false,
"observers": [],
"closed": false,
"isStopped": false,
"hasError": false,
"thrownError": null,
"_value": {
"entities": {},
"ids": [],
"loading": true,
"error": null,
"aircraft_id": 18737,
"manufacturer_id": 1,
"manufacturer_name": "Cessna Aircraft",
"model_id": 60,
"model_name": "172",
"model_variant": "N",
"model_subname": "Skyhawk",
"model_designator": "C172",
"serial_number": "17270821",
"registration": "C-GVNH",
"year_manufacture": 1978,
"mtom_kg": 1043,
"seats": null,
"address_hex": "c07d76",
"registration_status": "Registered"
}
}
},
"operator": {}
},
"operator": {}
},
"operator": {}
}
我只想知道如何简单地访问存储中的数据并显示它们。例如,假设“ manufacturer_name”。
这是我的aircraft.store.ts:
import { Injectable } from '@angular/core';
import { EntityStore, StoreConfig } from '@datorama/akita';
import { AircraftModel, AircraftState } from './aircraft.model';
export function createInitialState(): AircraftState {
return {
aircraft_id: null,
manufacturer_id: null,
manufacturer_name: null,
model_id: null,
model_name: null,
model_variant: null,
model_subname: null,
model_designator: null,
serial_number: null,
registration: null,
year_manufacture: null,
mtom_kg: null,
seats: null,
address_hex: null,
registration_status: null
};
}
export function createAircraft(aircraft: AircraftState) {
return { ...aircraft };
}
@Injectable({ providedIn: 'root' })
@StoreConfig({ name: 'aircraft', idKey: 'aircraft_id' })
export class AircraftStore extends EntityStore<AircraftState, AircraftModel> {
constructor() {
super(createInitialState());
}
set(data) {
//console.log('set function triggered');
const aircraft = createAircraft(data.body[0]);
this.update(aircraft);
}
}
这是aircraft.service.ts:
import { HttpClient, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ID } from '@datorama/akita';
import { Configuration } from '../../_constants/app.constants';
import { AircraftDataService } from './aircraft-data.service';
import { AircraftState } from './aircraft.model';
import { AircraftStore } from './aircraft.store';
@Injectable({ providedIn: 'root' })
export class AircraftService {
entities: AircraftState;
private actionUrl: string;
constructor(
private aircraftStore: AircraftStore,
private http: HttpClient,
private configuration: Configuration,
private aircrafDataService: AircraftDataService
) {
this.actionUrl = configuration.apiUrl;
}
get(aircraftId: ID) {
return this.aircrafDataService
.getAircraft(aircraftId)
.subscribe((response: HttpResponse<any>) => this.aircraftStore.set(response));
}
}
这是aircraft.query.ts:
import { Injectable } from '@angular/core';
import { QueryEntity } from '@datorama/akita';
import { AircraftModel, AircraftState } from './aircraft.model';
import { AircraftStore } from './aircraft.store';
@Injectable({ providedIn: 'root' })
export class AircraftQuery extends QueryEntity<AircraftState, AircraftModel> {
constructor(protected store: AircraftStore) {
super(store);
}
}
所以我的问题是:如何显示商店中的任何值?
提前感谢您一百万。
解决方案>>
由于正在处理可观察对象,因此需要使用Async Pipe。因此,在您的示例中,您将使用:
{{ (store_aircraft$ | async)?.manufacturer_name }}
了解我们为什么使用?。参见safe navigation operator
旁注
在您的aircraft.service.ts中,您订阅getAircraft。您应避免订阅服务,并应在进行调用的位置进行订阅,在大多数情况下,该调用将在组件中进行。
要完成此任务,
this.aircrafDataService .getAircraft(aircraftId) .pipe( tap(response => this.aircraftStore.set(response)) );
然后在组件中简单地执行:
this.aircrafDataService.getAircraft().subscribe();
需要考虑的另一件事是unsubscribing,但我留给您阅读。