Это было время, когда вам нужно было создать действия и редуктор для выполнения нескольких операций. Спасибо команде ngrx за создание ngrx / data. Это отличный шаблон l̶i̶b̶r̶a̶r̶y̶, с помощью которого вам не нужно создавать службы, действия и редукторы (в зависимости от требований).

Для базового приложения мы можем напрямую начать с файла ngrx / data.

Почему мы должны использовать ngrx / data?

Эта библиотека предоставляет несколько функций, а именно:

  1. Не нужно ничего создавать. Под чем-нибудь я подразумеваю действия, редукторы, эффекты, селекторы и бла-бла, конечно.
  2. Не нужно внедрять сервисный слой (Http one), он обрабатывается автоматически… умный Нет?
  3. Хранит данные как коллекцию в кеше… Ага! разве ты не этого хочешь?

и еще несколько…

Как это использовать?

Время действовать ...

Шаг 1. Установите библиотеки.

npm install @ngrx/effects @ngrx/entity @ngrx/store @ngrx/store-devtools @ngrx/data

Шаг 2. Создайте магазин и модуль

import { NgModule } from '@angular/core';
import { EntityDataModule } from '@ngrx/data';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { entityMetadata } from './zeus-store.meta';
import { DocumentService, SelectedDocumentService, SelectedPageService } from './zeus-store.service';
@NgModule({
imports: [
  StoreModule.forRoot({}, {}),
  EffectsModule.forRoot([]), 
  EntityDataModule.forRoot({ entityMetadata }),
  StoreDevtoolsModule.instrument(),
],
});
export class EmployeeStoreModule {}

На предыдущем шаге мы не сделали ничего особенного, кроме импорта модулей из библиотек.

  • Create Store-meta: Создайте файл с любым именем! Но я предпочитаю store-meta, поскольку он содержит метаданные, относящиеся к store
export const entityMetadata: EntityMetadataMap = { }

Что, черт возьми, это: @?

Это объект, у которого будет сопоставитель для хранилища сущностей, все еще не получили его? Проще говоря, этот объект будет иметь объект с именем сущности, например сотрудник, и этот объект будет иметь некоторые другие определения и функции, например:

  • entityName - entityName типа является единственным обязательным свойством метаданных. Это уникальный ключ метаданных типа объекта в кэше.
  • entityDispatcherOptions
  • filterFn: функция фильтра, если вы хотите отфильтровать что-то из кеша сущностей
  • selectId: поскольку в объекте данных обязательно должно быть свойство id, и если у ваших данных нет свойства id, он завершится ошибкой. Чтобы исправить это, мы можем использовать это свойство, которое будет получать и возвращать уникальный идентификатор.
  • sortComparer: для создания сортировщика данных сущности

Пример:

export function getUserId(user: JWTUser): string {
  return user.sub;
}
export const entityMetadata: EntityMetadataMap = {
 Employee: {
   entityName: 'Employee',
   selectId: getUserId,
   ...
},
  • Создать услугу

Эта служба реализует ваши методы Http и добавит данные по умолчанию в магазин.

@Injectable({providedIn: 'root'})
export class EmployeeService extends EntityCollectionServiceBase<Employee> {
constructor(serviceElementsFactory:     EntityCollectionServiceElementsFactory) {
   super('Employee', serviceElementsFactory);
  }
}
  • Внедрить службу данных по умолчанию (конфигурация для переопределения установщика HTTP по умолчанию)
const defaultDataServiceConfig: DefaultDataServiceConfig = { 
    root: 'https://my-api-domain.com:8000/api/v1',
    timeout: 3000, // request timeout 
}
// add this in your module as well 
  providers: [
     { provide: DefaultDataServiceConfig, useValue:    defaultDataServiceConfig }
  ]

Шаг 3. Используйте это

И ... мы сейчас на шаге 3, я знаю, что это более 3 шагов, но это то, что мы называем микрошагами: D

Теперь давайте посмотрим, как мы можем использовать эту услугу.

constructor(private service: EmployeeService) {
    this.service.getById('employeeId').subscribe(response => {
    // do what ever you want to do with data...
    })
}

Чего ждать? но я никогда не создавал метод getById в службе моих сотрудников. А вот и волшебство, которое наша служба сотрудников расширяет до класса EntityCollectionServiceBase. Это класс, в котором есть все шаблоны для нас, и только оттуда вы получаете весь метод. Реализованная нами служба по умолчанию имеет конечную точку API, поэтому конечный URL-адрес будет.

https://my-api-domain.com:8000/api/v1/entiyName
in our case it will be
https://my-api-domain.com:8000/api/v1/Employees (adding s by default by default service to make it plural)

После вызова вашего метода getById

  1. Он попадет в API
  2. Он сохранит результат в магазине ngrx

Бум… и готово.

Но вы знаете, что? Я не хочу использовать эту службу HTTP по умолчанию, а хочу, чтобы все управление HTTP было в моих руках? Что я должен делать? хм ... давай посмотрим

Изучив больше, я обнаружил, что служба моих сотрудников имеет некоторые встроенные методы, такие как addOneToCache и некоторые другие, поэтому я поэкспериментировал с этим и нашел результат. Пример :

getEmployeeById() {
  return     this.httpService.get('https:someurl.com/employee/1').pipe(map((response)=> {
   this.addOneToCache(response);
   return of(response);
 }));
}

и это тоже сделано… :)

Что ж, если вы хотите узнать больше о доступных методах, вы всегда можете перейти на сайт https://ngrx.io/guide/data/entity-dataservice

Надеюсь, вам понравятся мои работы ... и, кстати, вы можете хлопать максимум 50 раз: D