Итак, у меня есть компонент под названием custom-modal.component
. HTML-файл выглядит следующим образом:
<dialog id = "custom-modal">
<ng-content></ng-content>
</dialog>
В файле .ts
у меня есть
this.modal = document.querySelector('#modal-custom');
// Buttons listeners to showModal() and close() methods...
Проблема возникает, если я пытаюсь вызвать modal несколько раз:
<button class = "open-modal">See cards</button>
<button class = "open-modal">See flowers</button>
<app-custom-modal>
<app-cards></app-cards>
</app-custom-modal>
<app-custom-modal>
<app-flowers></app-flowers>
</app-custom-modal>
Итак, в Angular это будет выглядеть так:
<button class = "open-modal">See cards</button>
<button class = "open-modal">See flowers</button>
*** NOTE that there's two ***
<dialog id = "custom-modal">
<div> <h1> Cards title </h1> </div>
</dialog>
<dialog id = "custom-modal">
<div> <h1> Flowers title </h1> </div>
</dialog>
querySelector не будет работать, так как он выбирает только первый. Я могу сделать querySelectorAll и перебрать все модальные окна, но тогда у меня нет способа назначить прослушиватель кнопок для отображения правильного модального окна (или я не знаю, как это сделать).
Я не знаю, есть ли лучший способ решить эту проблему, я просто хочу сделать ее полностью пригодной для повторного использования. Извините за нубские вопросы, так как я младший разработчик. Заранее спасибо.
🤔 А знаете ли вы, что...
С помощью JavaScript можно создавать клиентские приложения для мобильных устройств с использованием фреймворков, таких как React Native и NativeScript.
Важно помнить, где вы хотите обрабатывать открытое/закрытое состояние вашего диалога.
В этом случае вы делаете это в компоненте, в котором находится модальное окно. Что вы можете сделать, так это передать ввод, скажем, видимый, модальному, который указывает открытое/закрытое состояние. Вы также можете определить вывод, который уведомляет вас, если модальное окно получило команду закрыться из модального компонента.
Я также рекомендую вам использовать ViewChild в модальном компоненте вместо document.querySelector(...). Обратите внимание, что при использовании ViewChild вам, скорее всего, придется использовать хук жизненного цикла AfterViewInit.
.ts файл CustomModalComponent
import { Component, OnInit, AfterViewInit, ViewChild, ElementRef, Input, Output, EventEmitter } from '@angular/core';
// ... the rest of import
@Component({
// ... Component decorator props (selector, templateUrl, styleUrls)
})
export class CustomModalComponent implements OnInit, AfterViewInit {
@ViewChild('modalRef') modalRef: ElementRef;
@Input() visible: boolean;
// Optional if you want to close the dialog from here and notify the parent (host)
@Output() closed = new EventEmitter();
constructor() { }
ngAfterViewInit(): void {
// Print the HTMLElement of the modal
console.info(this.modalRef.nativeElement);
// Do your thing
}
close() {
this.closed.emit();
// ...
}
// ... the rest of the component
}
.html CustomModalComponent
<dialog #modalRef>
<ng-content></ng-content>
</dialog>
Затем, когда вы хотите использовать его в ParentComponent
В вашем .html
<button class = "open-modal" (click) = "openCards()">See cards</button>
<button class = "open-modal" (click) = "openFlowers()">See flowers</button>
<app-custom-modal [visible] = "visibleCards" (closed) = "closeCards()">
<app-cards></app-cards>
</app-custom-modal>
<app-custom-modal [visible] = "visibleFlowers" (closed) = "closeFlowers()">
<app-flowers></app-flowers>
</app-custom-modal>
В вашем .ts
import { Component } from '@angular/core';
// ... the rest of import
@Component({
// ... Component decorator props (selector, templateUrl, styleUrls)
})
export class ParentComponent {
visibleCards: boolean;
visibleFlowers: boolean;
constructor() { }
openCards() {
this.visibleCards = true;
// ...
}
openFlowers() {
this.visibleFlowers = true;
// ...
}
closeCards() {
this.visibleCards = false;
// ...
}
closeFlowers() {
this.visibleFlowers = false;
// ...
}
// ... the rest of the component
}