Задать вопрос
@Vs4512

Как предотвратить потерю данных в модальном окне при использовании content projection в Angular?

При реализации модального окна с использованием ng-content (content projection) возникает критичная проблема: контент переданный в неё затирается. Сейчас модалка сразу же открывается при входе в приложение и только в этот момент данные отображаются(для дебага)

Как должно работать:
Пользователь жмет кнопку
Открывается модалка с контентом переданным в нее(любая форма)

Суть в том, что через ng-content можно было бы отправлять в модалку компоненты или html, эдакий конструктор.

Реализация сейчас:
service:
export class ModalService {
  containerModal?: ViewContainerRef;
  modalRef?: ComponentRef<any>;

  registerModalContainer(container: ViewContainerRef): void {
    this.containerModal = container;
  }

  show(component: any) {
    if (!this.containerModal) return;
    this.modalRef = this.containerModal.createComponent(component);
  }

  destroy(): void {
    if (this.modalRef) {
      this.modalRef.destroy();
    }
  }
}

модалка:
export class ModalService {
  containerModal?: ViewContainerRef;
  modalRef?: ComponentRef<any>;

  registerModalContainer(container: ViewContainerRef): void {
    this.containerModal = container;
  }

  show(component: any) {
    if (!this.containerModal) return;
    this.modalRef = this.containerModal.createComponent(component);
  }

  destroy(): void {
    if (this.modalRef) {
      this.modalRef.destroy();
    }
  }
}

@if (close()){
<div class="overlay">
  <div class="window_modal" >
    <button class="clear_btn" (click)="onClose()">
      <svg icon="cross" class="svg10"></svg>
    </button>
    <ng-content>

    </ng-content>
    </div>
  </div>}

Host:
@Component({
  selector: 'tt-host-modal',
  imports: [],
  templateUrl: `/host-modal.component.html`,
  styleUrl: './host-modal.component.scss',
})
export class HostModalComponent implements AfterViewInit, OnDestroy {
  @ViewChild('modalHost',  { read: ViewContainerRef })

  containerRef?: ViewContainerRef;
  modalService = inject(ModalService);

  ngAfterViewInit(): void {
    if (!this.containerRef) {return;}
    this.modalService.registerModalContainer(this.containerRef)
  }

  ngOnDestroy(): void {
    this.modalService.destroy();
  }}

<ng-template #modalHost></ng-template>
страница с модалкой:
@Component({
  selector: 'tt-community-page',
  imports: [
    CommunityCardComponent,
    CommunityFiltersComponent,
    SvgIconComponent,
    InfiniteScrollTriggerComponent,
    WindowModalComponent,
  ],
  templateUrl: './community-page.component.html',
  styleUrl: './community-page.component.scss',
})
export class CommunityPageComponent {
  #store = inject(Store);
  modalService = inject(ModalService);

  communities$ = this.#store.selectSignal(communityFeature.selectCommunityFiltered);

  timeToFetch() {
    this.#store.dispatch(filtercommunityActions.setPage({ page: 1 }));
  }

  createCommunityModal(): void {
    this.modalService.show(WindowModalComponent)
  }
}


<code lang="html">
<div class="btn-wrapper">
  <h1>Cообщества</h1>
  <button class="btn" (click)="createCommunityModal()">Создать сообщество
    <svg icon="content" class="svg16 "></svg>
  </button>
</div>

<tt-window-modal>
  Habr
</tt-window-modal>

<tt-community-filters></tt-community-filters>

<div class="wrapper-for">
  @for (community of communities$(); track community.id; let last = $last) {
    <tt-community-card [community]="community"></tt-community-card>

    @if (last) {
      @defer (on viewport) {
        <tt-infinite-scroll-trigger
          (loaded)="timeToFetch()"
        ></tt-infinite-scroll-trigger>
      } @placeholder {
        <div></div>
      }
    }
  }
</div>

</code>
  • Вопрос задан
  • 46 просмотров
Подписаться 2 Средний Комментировать
Помогут разобраться в теме Все курсы
  • OTUS
    Angular Developer
    5 месяцев
    Далее
  • Учебный центр IBS
    WEB-022 Разработка на Angular. Продвинутый уровень
    1 неделя
    Далее
  • Академия Eduson
    Frontend-разработчик
    9 месяцев
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы