Angular 9 - значение Datorama Akita из магазина - PullRequest
0 голосов
/ 15 января 2020

В настоящее время я пытаюсь настроить простую форму в Angular 8, используя Акиту. Прежде чем идти дальше, я должен сказать вам, что я не разработчик, и я совершенно новичок в мире Angular ... Даже не упоминая концепции управления состоянием. Пожалуйста, помните об этом при чтении моего кода:)

Вот краткое описание того, чего я пытаюсь достичь. Пользователь вводит первые символы регистрационного номера на входе. Ниже в автозаполнении предлагаются регистрационные номера, известные в базе данных. Когда пользователь выбирает одно из этих значений, служба запускается с соответствующим идентификатором и получает данные для выбранного транспортного средства (в данном случае воздушного судна). И возвращенные данные отображаются под окном выбора.

Пока все хорошо ... Мой блок автозаполнения работает хорошо, и хранилище заполнено (очевидно), как и ожидалось. Я вижу правильные данные в магазине, используя Redux devtools.

enter image description here

Моя проблема возникает, когда я пытаюсь отобразить данные ... Я могу увидеть весь объект в магазине на своей странице с чем-то как {{ 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": {}
}

Я просто хотел бы знать, как просто получить доступ к данным в магазине и отобразить их. Скажем, например, «имя_производителя».

Вот мой самолет.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);
  }
}

Вот самолет.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);
  }
}

Итак, мой вопрос: Как вывести любое значение из магазина?

Заранее спасибо за миллион за вашу помощь.

1 Ответ

0 голосов
/ 16 января 2020

Решение

Поскольку вы имеете дело с наблюдаемой, вам нужно будет использовать Asyn c Pipe . Итак, в вашем примере вы бы использовали:

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

Чтобы прочитать о том, почему мы используем? см. оператор безопасной навигации

Примечание к сведению

В своем сайте aircraft.service.ts вы получаете подписку на getAircraft. Вам следует избегать подписки на услуги и подписываться на места совершения вызова, который в большинстве случаев будет в компоненте.

Для выполнения sh это

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

Затем в Компонент просто делает:

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

Еще одна вещь, которую необходимо учитывать, это отмена подписки , но я оставлю это для вас, чтобы прочитать о.

...