如何使用 querySelector 多次调用同一个 angular 组件
How to call the same angular component multiple times using querySelector
所以我有一个名为 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...
如果我尝试多次调用模态,就会出现问题:
<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 并循环遍历每个模态,但是我无法分配按钮侦听器以显示正确的模态(或者我不知道该怎么做)。
不知道有没有更好的办法解决这个问题,我只是想让它完全可重用。抱歉,我是初级开发人员,所以有菜鸟问题。提前致谢。
其中一个重要的部分是牢记您要在何处处理对话的 open/close 状态。
在这种情况下,您是在承载模态的组件中执行此操作。您可以做的是将输入(比方说可见)传递给指示 open/closed 状态的模态。您还可以定义一个输出,通知您是否命令从模态组件内关闭模态。
我还建议您在模态组件中使用 ViewChild 而不是 document.querySelector(...)。请注意,在使用 ViewChild 时,您很可能必须使用 AfterViewInit 生命周期挂钩。
.CustomModalComponent 的 .ts 文件
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.log(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
}
所以我有一个名为 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...
如果我尝试多次调用模态,就会出现问题:
<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 并循环遍历每个模态,但是我无法分配按钮侦听器以显示正确的模态(或者我不知道该怎么做)。
不知道有没有更好的办法解决这个问题,我只是想让它完全可重用。抱歉,我是初级开发人员,所以有菜鸟问题。提前致谢。
其中一个重要的部分是牢记您要在何处处理对话的 open/close 状态。
在这种情况下,您是在承载模态的组件中执行此操作。您可以做的是将输入(比方说可见)传递给指示 open/closed 状态的模态。您还可以定义一个输出,通知您是否命令从模态组件内关闭模态。
我还建议您在模态组件中使用 ViewChild 而不是 document.querySelector(...)。请注意,在使用 ViewChild 时,您很可能必须使用 AfterViewInit 生命周期挂钩。
.CustomModalComponent 的 .ts 文件
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.log(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
}