在 Angular 8 中有一个可重用的模态组件
Have a reusable modal component in Angular 8
我正在使用 Angular 8 和 ng-boostrap 5.2.2。
我想要一个可重用的模态组件:
在模式中单击图像时将其关闭,然后return我将图像的值
能够从 parent 组件调用打开模式函数,我可以在我想要的元素上执行 (onclick)
我可以从 child 组件而不是 parent 组件执行此操作。
到目前为止我做了什么:
champion-modal-component.html
(child)
<ng-template #mymodal let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Bootstrap Modal</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.close('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="selected">
<img (click)="getSelectedChampion('aatrox')" class="selected-image" src="../../../../../assets/champions/aatrox.png" alt="aatrox" title="aatrox">
<img (click)="getSelectedChampion('ahri')" class="selected-image" src="../../../../../assets/champions/ahri.png" alt="ahri" title="ahri">
<img (click)="getSelectedChampion('akali')" class="selected-image" src="../../../../../assets/champions/akali.png" alt="akali" title="akali">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-dark" (click)="modal.close('Close click')">
Close
</button>
</div>
</ng-template>
<button class="btn btn-lg btn-primary" (click)="open(mymodal)">
Open My Modal
</button>
champion-modal-component.ts
(child)
import { Component, OnInit, Input } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-champion-modal',
templateUrl: './champion-modal.component.html',
styleUrls: ['./champion-modal.component.scss']
})
export class ChampionModalComponent implements OnInit {
championSelected = '';
constructor(private modalService: NgbModal) { }
ngOnInit() {
}
open(content: any) {
this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title' });
}
getSelectedChampion(champion: string) {
console.log('champion: ', champion);
this.modalService.dismissAll();
this.championSelected = champion;
}
}
champion-suggestion-component.html
(parent)
<!-- I WOULD LIKE THIS and not use a button in the child -->
<img (click)="openModal()" class="suggestion-image"
src="../../../../../assets/champions/aatrox.png" alt="aatrox" title="aatrox">
<app-champion-modal></app-champion-modal>
这是否可以通过模态服务或 EventEmitter 实现?
您可能正在寻找的是 @Output()
。
使用它时,您应该能够在关闭 child.
组件时 return 一个值或在 parent 组件上调用一个方法
Child:
// ts
@Output() close = new EventEmitter<any>();
// html
<div (click)="close.emit(value)"></div>
Parent:
// html
<child-el (close)="functiontoCall($event)"></child-el>
// ts
functiontoCall(event: any) {
console.log(event);
this.closeChild(); // hypthetical function to close the child
}
您可以将此代码调整为 return 单击图像时的图像值。
在您的情况下,child 是图像组件,parent 是这些图像的容器。
我终于用服务做到了:
champion-modal.component.html
(child)
<div class="modal-header">
<h4 class="modal-title">Select a Champion</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.close('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="modal-body">
<div class="search-container">
<div class="image-container">
<div *ngFor="let image of championImages" class="medium-name-circle">
<img (click)="getSelectedChampion(image.value)" class="medium-name-image"
src="../../../../../assets/champions/{{image.value}}.png" alt="{{image.value}}"
title="{{image.viewValue}}">
<div class="text">{{image.viewValue}}</div>
</div>
</div>
</div>
champion-modal.component.ts
(child)
constructor(public activeModal: NgbActiveModal, private modalService: ChampionModalService) { }
ngOnInit() {
}
getSelectedChampion(champion: string) {
this.activeModal.close();
this.championSelected = champion;
this.modalService.getSelectedChampion(this.championSelected);
}
champion-modal.service.ts
import { Injectable } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ChampionModalComponent } from './champion-modal.component';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ChampionModalService {
// Observable string sources
private componentMethodCallSource = new Subject<any>();
// Observable string streams
componentMethodCalled$ = this.componentMethodCallSource.asObservable();
roleSelected = '';
teamSelected = '';
constructor(private modal: NgbModal) { }
open() {
this.modal.open(ChampionModalComponent, { size: 'lg' });
}
getSelectedChampion(champion: string) {
this.componentMethodCallSource.next({
championName: champion,
role: this.roleSelected,
team: this.teamSelected
});
}
}
champion-suggestion.component.html
(parent)
<img (click)="openModal(role, 'yourTeam')" class="suggestion-image"
src="../../../../../assets/champions/aatrox.png" alt="aatrox" title="aatrox">
champion-suggestion.component.ts
(parent)
constructor(private modalService: ChampionModalService) {
// Callback of the modal
this.modalService.componentMethodCalled$.subscribe(
(parameters) => {
this.setSelectedChampion(parameters.role, parameters.championName, parameters.team);
}
);
}
ngOnInit() {
}
setSelectedChampion(role: string, champion: string, team: string) {
if (team === 'yourTeam') {
this.yourTeamRole[role] = champion;
}
if (team === 'enemyTeam') {
this.enemyTeamRole[role] = champion;
}
}
openModal(role: string, team: string) {
this.modalService.roleSelected = role;
this.modalService.teamSelected = team;
this.modalService.open();
}
我有 Circular dependency detected
警告,我可以避免吗?
我正在使用 Angular 8 和 ng-boostrap 5.2.2。 我想要一个可重用的模态组件:
在模式中单击图像时将其关闭,然后return我将图像的值
能够从 parent 组件调用打开模式函数,我可以在我想要的元素上执行 (onclick)
我可以从 child 组件而不是 parent 组件执行此操作。
到目前为止我做了什么:
champion-modal-component.html
(child)
<ng-template #mymodal let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Bootstrap Modal</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.close('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="selected">
<img (click)="getSelectedChampion('aatrox')" class="selected-image" src="../../../../../assets/champions/aatrox.png" alt="aatrox" title="aatrox">
<img (click)="getSelectedChampion('ahri')" class="selected-image" src="../../../../../assets/champions/ahri.png" alt="ahri" title="ahri">
<img (click)="getSelectedChampion('akali')" class="selected-image" src="../../../../../assets/champions/akali.png" alt="akali" title="akali">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-dark" (click)="modal.close('Close click')">
Close
</button>
</div>
</ng-template>
<button class="btn btn-lg btn-primary" (click)="open(mymodal)">
Open My Modal
</button>
champion-modal-component.ts
(child)
import { Component, OnInit, Input } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-champion-modal',
templateUrl: './champion-modal.component.html',
styleUrls: ['./champion-modal.component.scss']
})
export class ChampionModalComponent implements OnInit {
championSelected = '';
constructor(private modalService: NgbModal) { }
ngOnInit() {
}
open(content: any) {
this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title' });
}
getSelectedChampion(champion: string) {
console.log('champion: ', champion);
this.modalService.dismissAll();
this.championSelected = champion;
}
}
champion-suggestion-component.html
(parent)
<!-- I WOULD LIKE THIS and not use a button in the child -->
<img (click)="openModal()" class="suggestion-image"
src="../../../../../assets/champions/aatrox.png" alt="aatrox" title="aatrox">
<app-champion-modal></app-champion-modal>
这是否可以通过模态服务或 EventEmitter 实现?
您可能正在寻找的是 @Output()
。
使用它时,您应该能够在关闭 child.
组件时 return 一个值或在 parent 组件上调用一个方法Child:
// ts
@Output() close = new EventEmitter<any>();
// html
<div (click)="close.emit(value)"></div>
Parent:
// html
<child-el (close)="functiontoCall($event)"></child-el>
// ts
functiontoCall(event: any) {
console.log(event);
this.closeChild(); // hypthetical function to close the child
}
您可以将此代码调整为 return 单击图像时的图像值。 在您的情况下,child 是图像组件,parent 是这些图像的容器。
我终于用服务做到了:
champion-modal.component.html
(child)
<div class="modal-header">
<h4 class="modal-title">Select a Champion</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.close('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="modal-body">
<div class="search-container">
<div class="image-container">
<div *ngFor="let image of championImages" class="medium-name-circle">
<img (click)="getSelectedChampion(image.value)" class="medium-name-image"
src="../../../../../assets/champions/{{image.value}}.png" alt="{{image.value}}"
title="{{image.viewValue}}">
<div class="text">{{image.viewValue}}</div>
</div>
</div>
</div>
champion-modal.component.ts
(child)
constructor(public activeModal: NgbActiveModal, private modalService: ChampionModalService) { }
ngOnInit() {
}
getSelectedChampion(champion: string) {
this.activeModal.close();
this.championSelected = champion;
this.modalService.getSelectedChampion(this.championSelected);
}
champion-modal.service.ts
import { Injectable } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ChampionModalComponent } from './champion-modal.component';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ChampionModalService {
// Observable string sources
private componentMethodCallSource = new Subject<any>();
// Observable string streams
componentMethodCalled$ = this.componentMethodCallSource.asObservable();
roleSelected = '';
teamSelected = '';
constructor(private modal: NgbModal) { }
open() {
this.modal.open(ChampionModalComponent, { size: 'lg' });
}
getSelectedChampion(champion: string) {
this.componentMethodCallSource.next({
championName: champion,
role: this.roleSelected,
team: this.teamSelected
});
}
}
champion-suggestion.component.html
(parent)
<img (click)="openModal(role, 'yourTeam')" class="suggestion-image"
src="../../../../../assets/champions/aatrox.png" alt="aatrox" title="aatrox">
champion-suggestion.component.ts
(parent)
constructor(private modalService: ChampionModalService) {
// Callback of the modal
this.modalService.componentMethodCalled$.subscribe(
(parameters) => {
this.setSelectedChampion(parameters.role, parameters.championName, parameters.team);
}
);
}
ngOnInit() {
}
setSelectedChampion(role: string, champion: string, team: string) {
if (team === 'yourTeam') {
this.yourTeamRole[role] = champion;
}
if (team === 'enemyTeam') {
this.enemyTeamRole[role] = champion;
}
}
openModal(role: string, team: string) {
this.modalService.roleSelected = role;
this.modalService.teamSelected = team;
this.modalService.open();
}
我有 Circular dependency detected
警告,我可以避免吗?