使用 ng-bootstrap 在模态中提交表单
Submit a form in a modal using ng-bootstrap
我只是想用 ng-boostrap 在模态中提交表单,它比应该的复杂得多,我使用 ng-boostrap 来避免 JQuery 永远不优雅的代码,但这是有代价的。。。有点郁闷,简单又普通的东西应该更直接一些。
这是我的模态模板:
<form (ngSubmit)="onSubmit()">
<ng-template #newCategory let-c="close" let-d="dismiss">
<div class="modal-header bg-primary text-white text-uppercase">
<h4 class="modal-title">{{ 'core.create_a_new_category' | translate | uppercase }}</h4>
<button type="button" class="close text-white" aria-label="Close" (click)="d()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" (click)="c('Save click')">
Add Category
</button>
</div>
</ng-template>
</form>
<!-- Button that trigger modal -->
<div align="center" class="mt-2">
<span class="mr-1">{{ 'core.want_to_create_custom_category' | translate }}</span>
<button class="btn btn-lg btn-outline-primary" (click)="open(newCategory)">
{{ 'core.add_custom_category' | translate }}
</button>
</div>
我的组件:
export class NewCategoryModalComponent implements OnInit {
constructor(
private modalService: NgbModal ) {
}
open(content) {
this.modalService.open(content, {size: 'lg', centered: true}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
}
使用这种方法,您必须将打开模态的按钮放在不太好的模态组件中。
使用该代码,我可以打开和关闭模式(我花了 2 个小时),但是现在,我的 onSubmit() 事件不再被拦截,所以操作没有完成。
我错过了什么?
使用组件作为模式内容可能比使用模板更容易。该过程显示在 ng-bootstrap documentation. The code below can be tested in this stackblitz.
模态内容组件:
下面的 NgbdModalContent
组件包含带有页眉、正文和页脚的表单。这将是模态的内容。单击提交按钮将触发 ngSubmit
Angular 事件。
HTML:
<form (ngSubmit)="onSubmit()">
<div class="modal-header">
<h4 class="modal-title">Hi there!</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Hello, {{name}}!</p>
</div>
<div class="modal-footer">
<button class="btn btn-outline-success" (click)="onClick()">Submit</button>
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
</form>
代码:
import { Component, Input } from '@angular/core';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
...
})
export class NgbdModalContent {
@Input() name;
constructor(public activeModal: NgbActiveModal) { }
onClick() {
console.log("Submit button was clicked!");
}
onSubmit() {
console.log("Form was submitted!");
this.activeModal.close("Submit");
}
}
模态分量:
模态组件有一个方法允许以 NgbdModalContent
组件的实例作为其内容打开模态:
@Component({
...
})
export class NgbdModalComponent {
constructor(private modalService: NgbModal) { }
open() {
const modalRef = this.modalService.open(NgbdModalContent);
modalRef.componentInstance.name = 'World';
}
}
AppModule:
NgbdModalContent
组件必须包含在模块的entryComponents
中:
import { NgbdModalComponent, NgbdModalContent } from './modal-component';
...
@NgModule({
...
declarations: [NgbdModalComponent, NgbdModalContent, ...],
entryComponents: [NgbdModalContent]
})
export class AppModule {}
在我的场景中,我想在 parent 组件中使用模板,并且仅将 child 作为表单。在这种情况下,它要求模块在 child 组件中声明,因此它不起作用。我所做的是使用 child 中的事件更新 parent 状态以关闭它。
Parent:
<ng-template #content let-modal>
<div class="modal-body">
<app-add-edit-emp [emp]="emp" (successEvent)='AddEditUpdateStatus($event)' *ngIf="ActivateAddEditEmpComp"></app-add-edit-emp>
</div>
</ng-template>
Child:
声明你的输出参数:
@Output() successEvent = new EventEmitter();
发出事件:
this.successEvent.emit(true);
在parent处理:
AddEditUpdateStatus(success){
if(success){
this.modalService.dismissAll("success");
}
}
如果我们像下面的代码一样将标签作为 rootNode,我们将失去主体滚动
<form [formGroup]="stockWatchListFrom" (ngSubmit)="onSubmit()">
<div class="modal-header">
<p class="modal-title">Title</p>
</div>
<div class="modal-body">
<div class="form-row">
<div class="form-group col">
<label>WatchListName</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" (click)="onSubmit()">Confirm</button>
<button type="button" class="btn btn-secondary btn-sm ml-3">Cancel</button>
</div>
</form>
我更喜欢这个例子
<div class="modal-header">
<p class="modal-title">Title</p>
</div>
<div class="modal-body">
<form [formGroup]="stockWatchListFrom" (ngSubmit)="onSubmit()">
<div class="form-row">
<div class="form-group col">
<label>WatchListName</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" (click)="onSubmit()">Confirm</button>
<button type="button" class="btn btn-secondary btn-sm ml-3">Cancel</button>
</div>
我只是想用 ng-boostrap 在模态中提交表单,它比应该的复杂得多,我使用 ng-boostrap 来避免 JQuery 永远不优雅的代码,但这是有代价的。。。有点郁闷,简单又普通的东西应该更直接一些。
这是我的模态模板:
<form (ngSubmit)="onSubmit()">
<ng-template #newCategory let-c="close" let-d="dismiss">
<div class="modal-header bg-primary text-white text-uppercase">
<h4 class="modal-title">{{ 'core.create_a_new_category' | translate | uppercase }}</h4>
<button type="button" class="close text-white" aria-label="Close" (click)="d()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" (click)="c('Save click')">
Add Category
</button>
</div>
</ng-template>
</form>
<!-- Button that trigger modal -->
<div align="center" class="mt-2">
<span class="mr-1">{{ 'core.want_to_create_custom_category' | translate }}</span>
<button class="btn btn-lg btn-outline-primary" (click)="open(newCategory)">
{{ 'core.add_custom_category' | translate }}
</button>
</div>
我的组件:
export class NewCategoryModalComponent implements OnInit {
constructor(
private modalService: NgbModal ) {
}
open(content) {
this.modalService.open(content, {size: 'lg', centered: true}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
}
使用这种方法,您必须将打开模态的按钮放在不太好的模态组件中。
使用该代码,我可以打开和关闭模式(我花了 2 个小时),但是现在,我的 onSubmit() 事件不再被拦截,所以操作没有完成。
我错过了什么?
使用组件作为模式内容可能比使用模板更容易。该过程显示在 ng-bootstrap documentation. The code below can be tested in this stackblitz.
模态内容组件:
下面的 NgbdModalContent
组件包含带有页眉、正文和页脚的表单。这将是模态的内容。单击提交按钮将触发 ngSubmit
Angular 事件。
HTML:
<form (ngSubmit)="onSubmit()">
<div class="modal-header">
<h4 class="modal-title">Hi there!</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Hello, {{name}}!</p>
</div>
<div class="modal-footer">
<button class="btn btn-outline-success" (click)="onClick()">Submit</button>
<button type="button" class="btn btn-outline-dark" (click)="activeModal.close('Close click')">Close</button>
</div>
</form>
代码:
import { Component, Input } from '@angular/core';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
...
})
export class NgbdModalContent {
@Input() name;
constructor(public activeModal: NgbActiveModal) { }
onClick() {
console.log("Submit button was clicked!");
}
onSubmit() {
console.log("Form was submitted!");
this.activeModal.close("Submit");
}
}
模态分量:
模态组件有一个方法允许以 NgbdModalContent
组件的实例作为其内容打开模态:
@Component({
...
})
export class NgbdModalComponent {
constructor(private modalService: NgbModal) { }
open() {
const modalRef = this.modalService.open(NgbdModalContent);
modalRef.componentInstance.name = 'World';
}
}
AppModule:
NgbdModalContent
组件必须包含在模块的entryComponents
中:
import { NgbdModalComponent, NgbdModalContent } from './modal-component';
...
@NgModule({
...
declarations: [NgbdModalComponent, NgbdModalContent, ...],
entryComponents: [NgbdModalContent]
})
export class AppModule {}
在我的场景中,我想在 parent 组件中使用模板,并且仅将 child 作为表单。在这种情况下,它要求模块在 child 组件中声明,因此它不起作用。我所做的是使用 child 中的事件更新 parent 状态以关闭它。
Parent:
<ng-template #content let-modal>
<div class="modal-body">
<app-add-edit-emp [emp]="emp" (successEvent)='AddEditUpdateStatus($event)' *ngIf="ActivateAddEditEmpComp"></app-add-edit-emp>
</div>
</ng-template>
Child: 声明你的输出参数:
@Output() successEvent = new EventEmitter();
发出事件:
this.successEvent.emit(true);
在parent处理:
AddEditUpdateStatus(success){
if(success){
this.modalService.dismissAll("success");
}
}
如果我们像下面的代码一样将标签作为 rootNode,我们将失去主体滚动
<form [formGroup]="stockWatchListFrom" (ngSubmit)="onSubmit()">
<div class="modal-header">
<p class="modal-title">Title</p>
</div>
<div class="modal-body">
<div class="form-row">
<div class="form-group col">
<label>WatchListName</label>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" (click)="onSubmit()">Confirm</button>
<button type="button" class="btn btn-secondary btn-sm ml-3">Cancel</button>
</div>
</form>
我更喜欢这个例子
<div class="modal-header">
<p class="modal-title">Title</p>
</div>
<div class="modal-body">
<form [formGroup]="stockWatchListFrom" (ngSubmit)="onSubmit()">
<div class="form-row">
<div class="form-group col">
<label>WatchListName</label>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" (click)="onSubmit()">Confirm</button>
<button type="button" class="btn btn-secondary btn-sm ml-3">Cancel</button>
</div>