0

我目前正在尝试使用 Akita 在 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);
  }
}

所以我的问题是:如何显示商店的任何价值?

提前一百万感谢您的帮助。

4

1 回答 1

0

解决方案

由于您正在处理可观察对象,因此您需要使用Async Pipe。因此,在您的示例中,您将使用:

{{ (store_aircraft$ | async)?.manufacturer_name }}

阅读我们为什么使用 ?。见安全导航操作员

边注

在您的aircraft.service.ts 中,在get 中,您订阅了getAircraft。您应该避免订阅服务,并且应该在调用的地方订阅,在大多数情况下,这将在组件中。

要做到这一点,

this.aircrafDataService
  .getAircraft(aircraftId)
  .pipe(
      tap(response => this.aircraftStore.set(response))
  );

然后在组件中简单地做:

this.aircrafDataService.getAircraft().subscribe();

需要考虑的另一件事是取消订阅,但我会留给您阅读。

于 2020-01-16T02:07:30.113 回答