gpt4 book ai didi

angular - 如何使模式在 Angular 2 中可重用?

转载 作者:太空狗 更新时间:2023-10-29 17:21:05 25 4
gpt4 key购买 nike

编程时可重用性非常重要,我们可以做的任何减少代码重复的事情都会帮助我们。

我必须在我的 Angular 2 项目中的许多地方使用模态弹出窗口向用户显示信息。我正在使用 ng-bootstrap并且所有这些模态框都具有相同的页眉和页脚,但在许多情况下主体会发生变化。有时正文只是想替换单个占位符,有时准备动态内容有些复杂。这些由不同的组件触发或管理。

ng-bootstrap允许我们以两种方式将内容传递到模式中。

  1. 作为模板。这里将整个模态 html 包装在 <ng-template></ng-template>
  2. 作为组件

使用第一种方法,我必须为每个模态重复编写页眉、正文和页脚。

使用第二种方法,我可以将 HTML 包装在一个组件中,但需要放置占位符以使其动态化。这样我就可以按如下方式传递值

  open() {
const modalRef = this.modalService.open(NgbdModalContent);
modalRef.componentInstance.name = 'World';
}

但灵 active 仍然有限。

我想要实现的是使用 Content Projection [Transclusion] 制作一个重用模态组件

因此,在我的 Common Modal 主体中,如下所示。我放置了<ng-content></ng-content>作为 Modal 正文的插槽。

  @Component({
selector: 'common-modal',
template: `
<!-- Modal -->
<div class="modal fade" id="common-modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{{title}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<ng-content></ng-content>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
`,

现在我希望我可以像下面那样使用它。

<common-modal title="First Modal">
<span>Welcome Jasnan!</span>
</common-modal>

在其他地方

<common-modal title="Second Modal">   
//......
<tr *ngFor="let student of pagedStudents">
<td>
{{student.name}}
</td>
<td>
{{student.grade}}
</td>
</tr>
//......
</common-modal>

我该怎么做?在 ng-bootstrap 中有没有办法做到这一点? ?感谢您帮助我解决这个问题。

最佳答案

目前最好的解决方案是在共享模块(导出组件和服务的地方)中创建自定义可重用的模态组件模态服务,这样它可以在导入共享模块的任何其他模块中使用

shared.module.ts

@NgModule({
imports: [
CommonModule
],
declarations: [
ModalComponent,
],
providers:[
ModalService
],
exports:[
ModalComponent
]
})

modal.component.html

<div class="custom-modal">
<div class="model-close-btn">
<img class="close-image" src="assets/icon/png/close.png" alt="">
</div>
<ng-content></ng-content>
</div>

modal.component.ts

import { Component, OnInit, OnDestroy, ElementRef, Input } from '@angular/core';
import { ModalService } from '../services/modal.service';
import { element } from '@angular/core/src/render3';

@Component({
selector: 'custom-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.scss']
})
export class ModalComponent implements OnInit, OnDestroy {
@Input() id: string;
private element: any;

constructor(private modalService: ModalService, private el: ElementRef) {
this.element = el.nativeElement;
}

ngOnInit(): void {
let modal = this;

// ensure id attribute exists
if (!this.id) {
console.error('modal must have an id');
return;
}

// move element to bottom of page (just before </body>) so it can be displayed above everything else
document.body.appendChild(this.element);

// close modal on background click
this.element.addEventListener('click', function (e: any) {
if (e.target.className === 'modal__overlay modal__overlay--toggle') {
modal.close();
}
});

this.element.addEventListener('click', function (e: any) {
if (e.target.className === 'model-close-btn' || e.target.className === 'close-image' ) {
modal.close();
}
});

// add self (this modal instance) to the modal service so it's accessible from controllers
this.modalService.add(this);
}

// remove self from modal service when directive is destroyed
ngOnDestroy(): void {
this.modalService.remove(this.id);
this.element.remove();
}

// open modal
open(): void {
//console.log(this.element);
this.element.style.display = 'block';

}

// close modal
close(): void {
this.element.style.display = 'none';
}
}

modal.component.scss

/* MODAL STYLES
-------------------------------*/
:host(custom-modal) {
/* modals are hidden by default */
display: none;

}

.custom-modal-open {
/* body overflow is hidden to hide main scrollbar when modal window is open */
display: block !important;
}

.model-close-btn {
position: fixed;
width: 18px;
height: 18px;
right: 50px;
top: 50px;
z-index: 9999;
background-color: #fff;
border-radius: 50px;
padding: 10px;
cursor: pointer;

img {
width: 18px;
}
}

modal.service.ts

import { Injectable } from '@angular/core';

@Injectable({
providedIn: 'root'
})
export class ModalService {

private modals: any[] = [];

constructor() { }

add(modal: any) {
// add modal to array of active modals
this.modals.push(modal);
}

remove(id: string) {
// remove modal from array of active modals
this.modals = this.modals.filter(x => x.id !== id);
}

open(id: string) {
// open modal specified by id
let modal: any = this.modals.filter(x => x.id === id)[0];
modal.open();
}

close(id: string) {
// close modal specified by id
let modal: any = this.modals.filter(x => x.id === id)[0];
modal.close();
}

}

现在,如果您想在另一个模块的示例组件中使用此组件,请执行以下操作:

第 1 步:将共享模块导入要使用 custom-modal

的示例模块

sample.module.ts

@NgModule({
declarations: [
SampleComponent,
],
imports: [
SharedModule
],
})

第 2 步:

sample.component.ts

  import { ModalService } from 'src/shared/services/modal.service';


constructor(private modalService: ModalService){}

// call this function to open modal by passing modal id
openModal(id: string) {
this.modalService.open(id);
}

// just call this function to close modal by passing modal id
closeModal(id: string) {
this.modalService.close(id);
}

sample.component.html

<!-- modal popup started -->
<custom-modal id="custom-modal-one">

// add your any custom modal template code here and logic in sample.component.ts

</custom-modal>
<!-- modalp popup ends -->

关于angular - 如何使模式在 Angular 2 中可重用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44360691/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com