Перезапись дескриптора успеха NGRX DefaultPersistenceResultHandler - PullRequest
1 голос
/ 05 марта 2020

У меня возникли некоторые трудности с @ ngrx / data, и я надеюсь, что один из вас, Гениев, может мне помочь.

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

В соответствии с документацией я могу добавить AdditionalCollectionState, но мне нужен какой-то способ обновления свойств нового состояния.

Я подумал, что скопирую / вставлю пример кода, который у них есть в качестве основы и измените его так, чтобы он отражал мои собственные свойства .. проблема в том, что я немедленно получаю ошибку машинописного текста при действии => Action

Generi c type 'Action 'требуется аргумент (ы) одного типа

export class AdditionalPersistenceResultHandler  extends DefaultPersistenceResultHandler {

handleSuccess(originalAction: EntityAction): (data: any) => Action {
    const actionHandler = super.handleSuccess(originalAction);
    // return a factory to get a data handler to
    // parse data from DataService and save to action.payload
    return function(data: any) {
      const action = actionHandler.call(this, data);
      if (action && data && data.foo) {
        // save the data.foo to action.payload.foo
        (action as any).payload.foo = data.foo;
      }
      return action;
    };
  }
}

Я также не уверен, что это правильный путь к go по этому поводу или я собираюсь сделать это слишком сложным, могу ли я " просто "как-то вручную обновить состояние дополнительной коллекции (в моем вызове dataservice getWithQuery ()) и, если да, то какой будет наилучший / рекомендуемый подход.

Приветствия и благодарности

Гари

ОБНОВЛЕНИЕ

После того, как Эндрю указал на мою очевидную ошибку импорта, я теперь реализовал обработчик результатов, но получил следующую ошибку

ERROR in Error during template compile of 'AdditionalPropertyPersistenceResultHandler'
  Class AdditionalPropertyPersistenceResultHandler in D:/dev/angular/ng-vet/src/app/treatments/services/treatments-entity-result-handler.ts extends from a Injectable in another compilation unit without duplicating the decorator
    Please add a Injectable or Pipe or Directive or Component or NgModule decorator to the class.

, которая не делает никаких смысл суть Дело в том, что stackblitz не имеет его, и он прекрасно работает.

my entityMetadataMap

const entityMetadata: EntityMetadataMap = {
  TreatmentTemplate: {
    entityDispatcherOptions: {
      optimisticUpdate: true
    }
  },
  Treatment: {
    additionalCollectionState: {
      totalRecords: 0
    },
    entityDispatcherOptions: {
      optimisticUpdate: true
    }
  }
};

и провайдеров:

providers: [
    TreatmentsDataService,
    TreatmentEntityService,
    TreatmentTemplateResolver,
    TreatmentTemplatesDataService,
    TreatmentTemplateEntityService,
    {
      provide: PersistenceResultHandler,
      useClass: AdditionalPropertyPersistenceResultHandler
    },
    {
      provide: EntityCollectionReducerMethodsFactory,
      useClass: AdditionalEntityCollectionReducerMethodsFactory
    }
  ]

Я в основном скопировал вставленные методы из стекаблиц ..

в ^ 8.0. 2 из angular и ^ 8.6.0 из ngrx это может быть проблемой?

1 Ответ

1 голос
/ 05 марта 2020

Существует одно предупреждение для использования additionalCollectionState.

По умолчанию редуктор QUERY_MANY_SUCCESS ожидает, что action.payload.data будет массивом сущностей, но действие QUERY_MANY action.payload.data будет тем, что возвращает API.

Допустим, он возвращает

interface QueryManyAPIResponse<T> {
    total: number,
    entities: T[]
}

Вы можете добавить свойство total к полезной нагрузке действия, но action.payload.data должны быть объектами.

@Injectable()
export class AdditionalPersistenceResultHandler  extends DefaultPersistenceResultHandler {

    handleSuccess(originalAction: EntityAction): (data: any) => Action {
        const actionHandler = super.handleSuccess(originalAction);

        return function(data: any) {
            /** Default success action */
            const successAction = actionHandler.call(this, data);

            /** Change payload for query many */
            if (successAction && data && data.total) {
                (successAction as any).payload.total = data.total;
            }
            if (successAction && data && data.entities) {
                (successAction as any).payload.data = data.entities;
            }

            return action;
        };
    }
}

Это вносит изменения только к действию.

Хотя редуктор по умолчанию будет заботиться о сущностях, шаги 2 и 3 Документов NgRx необходимы для добавления итога как свойства в коллекцию сущностей.


нумерация страниц должна знать, сколько существует записей и сколько было загружено

сколько было загружено, выводится (id.length, поэтому вы можете использовать селектор для этого ) и, следовательно, его не нужно сохранять в хранилище.

У меня есть коллекция сущностей, и я хотел бы сохранить некоторую дополнительную информацию, чтобы сократить количество обращений к серверу и уменьшить избыточную загрузку.

Это сложная проблема. Самый чистый и прямой способ уменьшить количество вызовов API, который я обнаружил, - это использовать таблицу нумерации страниц на стороне сервера (см. Ссылку ниже) и предоставить страницу перед таблицей, которая предлагает панель мониторинга со статистикой (потребуется реализовать этот API) с различными фильтры и ссылки на страницу таблицы со встроенными параметрами запроса.

Мало кто тратит время на просмотр страниц с разбивкой по страницам, если данные уже находятся на странице 1.
А никто не хочет.

dashboard.component. html

        <button
          mat-raised-button
          [routerLink]="['/procurement/orders']"
          [queryParams]="{ awaitingPrices: 'yes', employeeID: userID }"
        >
          {{ statistics.awaitingPricesUser }}
        </button>

orders.component. html (контейнер)

<app-order-find (filter)="onFilter($event)"></app-order-find>
<app-order-filters
  [suppliers]="suppliers$ | async"
  [employees]="employees$ | async"
  [filters]="filters"
  (filtersUpdate)="updateFilters($event)"
></app-order-filters>
<app-orders-table
  [totalNumberOfOrders]="totalNumberOfOrders$ | async"
  [filters]="filters"
  (review)="onReview($event)"
  (edit)="onEdit($event)"
  (delete)="onDelete($event)"
>
  ></app-orders-table
>

Альтернативы

Ожидаете ли вы загрузить все данные в хранилище, т.е. в фоновую загрузку разбитых на страницы данных со страницы 1, 2, ..., последней страницы. Как только все данные загружены, вы можете полностью выполнить разбиение на страницы на стороне клиента с помощью селекторов.

Если вы ожидаете go вперед и назад между просмотром таблицы и подробностей или назад и вперед на тех же страницах и с теми же фильтрами, которые вы могли бы сделать сохраняйте карту кэша { urlWithQueryParams: entityIds } и используйте селекторы, чтобы получить из магазина. Вам нужно будет выбросить их, если вы удалите соответствующую сущность.

Ссылки

Таблица нумерации на стороне сервера - https://blog.angular-university.io/angular-material-data-table/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...