This is quite big project today
这次有以下几个功能:
1.ng-bootstrap模态框
2.响应式表单
3.响应式表单的验证
4.子窗关闭父窗口刷新
其实这几个哪一个都能写一个话题,事情太多了,时间紧任务重,一起写了吧:
ng-bootstrap模态框所需要的条件(very very important),如果写错,查错非常的难哦,请慎重【反正我看不懂错误提示,出个错解决老办天】。
1.package.json加入dependencies: "@ng-bootstrap/ng-bootstrap": "^1.0.0-beta.3", 也可以使用安装命令。
2.systemjs.config.js 加入map: '@ng-bootstrap/ng-bootstrap': 'node_modules/@ng-bootstrap/ng-bootstrap/bundles/ng-bootstrap.js',
3.app.module.tx 加入import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; 然后 imports: [NgbModule.forRoot()] //<--模态窗 【这个主module文件我分离开了几个子module】
4.app.module.tx 加入 entryComponents: [NgbmodalSubComponent] 【这是需要弹出的子窗口】
响应式表单所需要的条件
1.import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 然后 imports: [FormsModule,ReactiveFormsModule,]
2017.11.30增加
设置html控件的值. 因为很多时候需要做很多处理之后设置值,所以在createfrom时不能得到数据,或者不方便赋值.
//【patchValue设置部分控件的值】 【setValue({}) 需要设置全部表单中的值,如果缺少会报错】
this.heroForm.patchValue({ firstname: 'firstname2' });
--------------------------------------------以下是功能部分-------------------------------------------------------
Module文件
1 import { NgModule, } from '@angular/core' ; 2 import { BrowserModule } from '@angular/platform-browser' ; 3 import { NgbModule } from '@ng-bootstrap/ng-bootstrap' ; 4 import { NgbModalComponent } from './ngbmodal.component' ; 5 import { NgbmodalSubComponent } from './ngbmodal-sub.component' ; 6 import { FormsModule, ReactiveFormsModule } from '@angular/forms'; // <-- NgModel lives here 双向绑定 7 @NgModule({ 8 imports: [ 9 BrowserModule, 10 NgbModule.forRoot(), // <--模态窗 11 FormsModule, 12 ReactiveFormsModule, 13 ], 14 declarations: [ 15 NgbModalComponent, 16 NgbmodalSubComponent, 17 ], 18 entryComponents: [NgbmodalSubComponent] 19 }) 20 21 export class NgbmodalModule { }
父窗口:
1 import { Component, OnInit, Output } from '@angular/core' ; 2 import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap' ; 3 import { NgbmodalSubComponent } from './ngbmodal-sub.component' ; 4 5 @Component({ 6 selector: 'ngbmodalcomponent' , 7 templateUrl: 'app/app-ngbmodal/ngbmodal.component.html' , 8 providers: [NgbmodalSubComponent] 9 }) 10 11 export class NgbModalComponent implements OnInit { 12 title = "NgbModalComponent" ; 13 srefresh: string; 14 delay: number = 1000 ; 15 isLoading: boolean = false ; 16 constructor(private myNgbModal: NgbModal) { } 17 18 ngOnInit(): void { 19 20 } 21 open() { 22 const modalRef = this .myNgbModal.open(NgbmodalSubComponent, { windowClass: 'dark-modal', size: 'lg' }); 23 // 传给子窗口的值 24 modalRef.componentInstance.name = '传值' ; 25 // then回调,得到子窗口的返回的值。 26 modalRef.result.then((result) => { 27 // 只有返回ok才刷新父窗口 28 if (result == 'ok' ) { 29 this .refresh(); 30 } 31 }) 32 } 33 // 等待3秒钟之后在处理之后的逻辑【某些特殊需要,可以忽略】 34 refresh() { 35 this .isLoading = true ; 36 this .srefresh = '' ; 37 setTimeout(() => { 38 this .srefresh = "刷新成功" + new Date(); 39 this .isLoading = false ; 40 }, this .delay * 3 ); 41 42 } 43 }
1 {{title}} 2 < div > 3 窗口{{srefresh}} 4 < br /> 5 < input type ="button" (click) ="open()" value =" open " /> 6 7 < input type ="button" (click) ="refresh()" value =" 刷新 " /> 8 </ div >
子窗口:
1 import { Component, OnInit, ViewEncapsulation, Input, Output, EventEmitter } from '@angular/core' ; 2 import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' ; 3 import { FormControl, FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms' ; 4 5 @Component({ 6 selector: 'NgbmodalSubComponent' , 7 templateUrl: 'app/app-ngbmodal/ngbmodal-sub.component.html' 8 }) 9 export class NgbmodalSubComponent implements OnInit { 10 11 @Input() name: string; 12 heroForm: FormGroup; 13 14 constructor(public myNgbActiveModal: NgbActiveModal, private fb: FormBuilder) { } 15 16 ngOnInit(): void { 17 this .createForm(); 18 } 19 20 createForm() { 21 this .heroForm = this .fb.group({ //使用fromBuilder只是单纯简化了程序的,可以使用fromGorup 和fromControl的组合。 22 firstname: ['', [Validators.required, Validators.minLength(3 )]], //多个验证参数 23 lastname: ['', [Validators.required, this .skuValidator]], 24 email: ['', this .emailValidator], //可空可以通过或者邮箱验证,如果使用Validators.emaill 不能证验空值,等于必填,所以要单写一个正则表达式 25 age: ['', this .ageValidator], 26 }); 27 } 28 ageValidator(control: FormControl): { [s: string]: boolean } { 29 if (!control.value.match(/^$|^[0-9]*$/ )) { 30 return { invalidage: true }; 31 } 32 } 33 34 skuValidator(control: FormControl): { [s: string]: boolean } { 35 if (!control.value.match(/^$|^123/ )) { 36 return { invalidSku: true }; 37 } 38 } 39 40 emailValidator(control: FormControl): { [s: string]: boolean } { 41 //【^$|】 这三个字符表示【可空或者】 42 if (!control.value.match(/^$|^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/ )) { 43 return { invalidemail: true }; 44 } 45 } 46 onSubmit(): void { 47 console.log("firstname=", this .heroForm.value.firstname); 48 this .myNgbActiveModal.close('ok' ); 49 } 50 51 close(str: string) { 52 this .myNgbActiveModal.close(str); //关闭子窗口时,主窗口的then方法才工作,否则一直等待。 53 } 54 }
html
1 < div class ="modal-header" > 2 < h4 class ="modal-title" > Hi there! </ h4 > 3 < button type ="button" class ="close" aria-label ="Close" (click) ="close('Cross X')" > 4 < span aria-hidden ="true" > × </ span > 5 </ button > 6 </ div > 7 < form [formGroup] ="heroForm" #formDir ="ngForm" (ngSubmit) ="onSubmit()" novalidate > 8 < div class ="modal-body" > 9 < p > Hello {{name}}! </ p > 10 < div class ="form-group" > 11 < label class ="center-block" > 12 firstname: 13 < input class ="form-control" formControlName ="firstname" > 14 </ label > 15 <!--heroForm.get('firstname').invalid 是获得fromControlName控件,官网写的后台有一个同名方法获得,报找不到invalid属性,大坑啊!!!! --> 16 < div *ngIf ="heroForm.get('firstname').invalid && (heroForm.get('firstname').dirty || heroForm.get('firstname').touched)" 17 class ="alert alert-danger" > 18 < div *ngIf ="heroForm.get('firstname').errors.required" > 19 firstname is required. 20 </ div > 21 < div *ngIf ="heroForm.get('firstname').errors.minlength" > 22 Name must be at least 3 characters long. 23 </ div > 24 25 </ div > 26 </ div > 27 < div class ="form-group" > 28 < label class ="center-block" > 29 lastname: 30 < input class ="form-control" formControlName ="lastname" > 31 </ label > 32 < div *ngIf ="heroForm.get('lastname').invalid && (heroForm.get('lastname').dirty || heroForm.get('lastname').touched)" 33 class ="alert alert-info" > 34 < div *ngIf ="heroForm.get('lastname').errors.required" > 35 Lastname is required. 36 </ div > 37 < div *ngIf ="heroForm.get('lastname').errors.invalidSku" > 38 Must is 123 start. 39 </ div > 40 </ div > 41 </ div > 42 43 < div class ="form-group" > 44 < label class ="center-block" > 45 age: 46 < input class ="form-control" formControlName ="age" > 47 </ label > 48 < div *ngIf ="heroForm.get('age').invalid && (heroForm.get('age').dirty || heroForm.get('age').touched)" 49 class ="alert alert-warning" > 50 < div *ngIf ="heroForm.get('age').errors.invalidage" > 51 age format is incorrect 52 </ div > 53 </ div > 54 </ div > 55 56 < div class ="form-group" > 57 < label class ="center-block" > 58 email: 59 < input class ="form-control" formControlName ="email" > 60 </ label > 61 < div *ngIf ="heroForm.get('email').invalid && (heroForm.get('email').dirty || heroForm.get('email').touched)" 62 class ="alert alert-warning" > 63 < div *ngIf ="heroForm.get('email').errors.invalidemail" > 64 email format is incorrect 65 </ div > 66 </ div > 67 </ div > 68 </ div > 69 < div class ="modal-footer" > 70 < button type ="submit" class ="btn btn-outline-dark" 71 [disabled] ="heroForm.invalid" > 72 Submit 73 </ button > 74 <!-- <button type="button" class="btn btn-default" 75 (click)="formDir.resetForm({})"> 76 Reset 77 </button> --> 78 < button type ="button" class ="btn btn-outline-dark" (click) ="close('Close click')" > Close </ button > <!--关闭方法--> 79 </ div > 80 </ form >
最后效果图:
等有空的时候,我会补写一些注解。That's all.
查看更多关于angular 使用bootstratp模态框+响应式表单+响应式表单的验证+子窗关闭父窗口刷新的详细内容...