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.