Каков рекомендуемый способ использования доменных служб в рамках общих служб в angular?

#angular

Вопрос:

Я новичок в угловом.

У меня есть много кода, который повторяется во многих моих компонентах. Что-то вроде этого:

 onScroll() {
    this.pageNumber  ;
    if (this.pageNumber <= this.pageLimit) {
        if (this.tableMode === FormMode.READ) {
            this.domainSpecificService.fetchPage(this.pageNumber, this.pageSize).subscribe(responses => {
                this.entities.push(...responses.content);
                this.numberOfElements  = responses.numberOfElements;
                this.totalElements = responses.totalElements;
            });
        } else if (this.tableMode === FormMode.FILTER) {
            if (this.pageNumber <= this.pageLimit) {
                this.domainSpecificService.fetchPage(this.pageNumber, this.pageSize, this.filter!).subscribe(responses => {
                    this.entities.push(...responses.content);
                    this.numberOfElements  = responses.numberOfElements;
                    this.totalElements = responses.totalElements;
                });
            }
        }
    }
}

openModal(formMode: FormMode, entity?: EntityType) {
    const modalRef = this.modalService.open(EntityModalComponent, { size: 'xl', scrollable: true });
    modalRef.componentInstance.formMode = formMode;
    modalRef.componentInstance.entity = entity;
    this.returnModalResult(modalRef);
}

returnModalResult(modalRef: NgbModalRef) {
    modalRef.componentInstance.returnedEntity.subscribe((response: { entity: EntityType, formMode: FormMode }) => {
        if (response.formMode === FormMode.CREATE) {
            this.pageNumber = 0;
            this.domainSpecificService.fetchPage(0, this.pageSize).subscribe(responses => {
                this.entities = [...responses.content];
                this.numberOfElements = 0;
                this.numberOfElements  = responses.numberOfElements;
                this.totalElements = responses.totalElements;
            });
        } else if (response.formMode === FormMode.UPDATE) {
            let itemIndex = this.entities.findIndex(item => item.id == response.entity.id);
            this.entities[itemIndex] = response.entity;
        } else if (response.formMode === FormMode.FILTER) {
            this.filter = response.entity;
            this.tableMode = FormMode.FILTER;
            this.pageNumber = 0;
            this.domainSpecificService.fetchPage(0, this.pageSize, this.filter).subscribe(responses => {
                this.entities = [...responses.content];
                this.numberOfElements = 0;
                this.numberOfElements  = responses.numberOfElements;
                this.totalElements = responses.totalElements;
            });
        }
    })
}
 

Домены Specificservice и modal являются единственными, которые варьируются от компонента к компоненту. Я хотел бы знать, каков рекомендуемый метод для таких случаев.

Отдельная служба, в которой мы передаем domainSpecificService в качестве аргумента от компонента?: onScroll(данные: состояние компонента, apiService: любой)

…Или наследование компонентов?

В настоящее время я использую swagger для создания уровня api, поэтому я не могу добавить к нему интерфейс crud. Хотя в любом типе я могу вызвать любой метод без интерфейсов, но это выглядит не очень хорошо (apiService.Страница выборки(…)).

Ответ №1:

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

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

Переместите все переменные, к которым осуществляется доступ, в базовый компонент и замените все ссылки на this.domainSpecificService на this.apiService:

 // base-table.component.ts;
interface ApiService {
   fetchPage: (pageNumber: number, pageSize: number, filter: any) => Observable<any>;
}

@Directive()
public BaseTableComponent {
  public pageNumber: number;
  public pageSize: number;
  public pageLimit: number;
  public entities: any[];
  public numberOfElements: number;
  public totalElements: number;
  public tableMode: FormMode;
  public filter: any;

  constructor(protected apiService: ApiService, protected modalService: ModaleService) {}

onScroll() {
    this.pageNumber  ;
    if (this.pageNumber <= this.pageLimit) {
        if (this.tableMode === FormMode.READ) {
            this.apiService.fetchPage(this.pageNumber, this.pageSize).subscribe(responses => {
                this.entities.push(...responses.content);
                this.numberOfElements  = responses.numberOfElements;
                this.totalElements = responses.totalElements;
            });
        } else if (this.tableMode === FormMode.FILTER) {
            if (this.pageNumber <= this.pageLimit) {
                this.apiService.fetchPage(this.pageNumber, this.pageSize, this.filter!).subscribe(responses => {
                    this.entities.push(...responses.content);
                    this.numberOfElements  = responses.numberOfElements;
                    this.totalElements = responses.totalElements;
                });
            }
        }
    }
}

openModal(formMode: FormMode, entity?: EntityType) {
    const modalRef = this.modalService.open(EntityModalComponent, { size: 'xl', scrollable: true });
    modalRef.componentInstance.formMode = formMode;
    modalRef.componentInstance.entity = entity;
    this.returnModalResult(modalRef);
}

returnModalResult(modalRef: NgbModalRef) {
    modalRef.componentInstance.returnedEntity.subscribe((response: { entity: EntityType, formMode: FormMode }) => {
        if (response.formMode === FormMode.CREATE) {
            this.pageNumber = 0;
            this.apiService.fetchPage(0, this.pageSize).subscribe(responses => {
                this.entities = [...responses.content];
                this.numberOfElements = 0;
                this.numberOfElements  = responses.numberOfElements;
                this.totalElements = responses.totalElements;
            });
        } else if (response.formMode === FormMode.UPDATE) {
            let itemIndex = this.entities.findIndex(item => item.id == response.entity.id);
            this.entities[itemIndex] = response.entity;
        } else if (response.formMode === FormMode.FILTER) {
            this.filter = response.entity;
            this.tableMode = FormMode.FILTER;
            this.pageNumber = 0;
            this.apiService.fetchPage(0, this.pageSize, this.filter).subscribe(responses => {
                this.entities = [...responses.content];
                this.numberOfElements = 0;
                this.numberOfElements  = responses.numberOfElements;
                this.totalElements = responses.totalElements;
            });
        }
    })
}
}
 

Используйте это в компоненте домена, подобном этому:

 // example-domain.component.ts

@Component(...)
public ExampleDomainComponent extends BaseTableComponent {
  constructor(domainService: DomainSpecificService, modalService: ModalService) {
    super(domainService, modalService);
  }
}