keyValuePipe
ngFor 跑到object或者Map类型的资料
<div *ngFor="let item of (data|keyvalue)">{{item.key}}--{{item.value}}</div> data = { userId: 1, id: 1, title: "delectus aut autem", completed: false }; 结果 completed--false id--1 title--delectus aut autem userId--1 排序 <div *ngFor="let item of (data|keyvalue:compareFn)">{{item.key}}--{{item.value}}</div> data = { userId: 1, id: 2, title: 10, completed: 8 }; compareFn(a, b) { return a.value - b.value }
Rxjs Generate
参数:
初始值,条件,重复,最后一个应该是每次值得修饰
for循环 const source = generate(0, x => x < 5, x => x + 1); source.subscribe(val => { console.log(val); }) 最后一个值修饰 const source = generate(0, x => x < 5, x => x + 1,x=>x+'!!!'); source.subscribe(val => { console.log(val); }) 0!!! 1!!! 2!!! 3!!! 4!!!
Rxjs repeat 重复
let soure = of(1).pipe(repeat(3));
soure.subscribe(val => {
console.log(val);
})
//重复3次
-1 的时候一直重复
Snapshot快照 :当不需要Observable 替换品
:id
console.log(this.router.snapshot.paramMap.get('id'));
Form
导入模块
module
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
@NgModule({
imports:[
FormsModule, ReactiveFormsModule
]
})
ts
第一种
names = new FormControl('');
修改
updateName() {
this.names.setValue('小明')
}
<label>name:
<input type="text" [formControl]="names">
</label>
第二种
profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl('')
});
点击修改值
clickDown() {
this.profileForm.patchValue({
firstName: 'yuanli',
lastName: 'xxx'
})
}
拿到提交的值
onSubmit() {
console.log(this.profileForm.value);
}
ngOnInit(): void {
// 监听值的变化
this.profileForm.valueChanges.subscribe(val=>{
console.log(val);
console.log(this.profileForm.getRawValue());// 这两个等价的
})
}
remove(){
this.profileForm.reset() //清空所有
}
html
<h1>{{profileForm.value|json}}</h1>
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<label>
firstName : <input type="text" formControlName="firstName">
</label> <br>
<label>
lastName : <input type="text" formControlName="lastName">
</label><br>
<button type="submit">Submit</button>
</form>
Reactive Forms
- AbstractControl
FormControl,FormControl,FormArray的抽象类别。 - FormControl
追踪某一个表单控制项的栏位值与验证状态。 - FormGroup
追踪某一个表单类别下控制项的栏位值与验证状态。 - FormArray追踪
一群表单控制项的栏位值与验证状态。
拿到某个特定的值
取得表单控制项
this.myForm.get('nickName')作为FormControl
取得表单分类
this.myForm.get('groupName')作为FormGroup
取得表单数组
this.myForm.get('arrayName')作为FormArray
取得分组下表单格式或控制项
this.myForm.get('groupName.nickName')
验证
this.myForm.get('nickName').valid
取得栏位验证错误讯息,若验证通过回传null
this.myForm.get('nickName').errors
验证整个表单是否通过验证
this.myForm.valid
表单验证
required
email
minlength
maxlength
pattern
献上一个完整版
ts
import {Component, OnInit} from '@angular/core';
import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
@Component({
selector: 'app-three',
templateUrl: './three.component.html',
styleUrls: ['./three.component.less']
})
export class ThreeComponent implements OnInit {
// myForm = new FormGroup({
// firstName: new FormControl(''),
// lastName: new FormControl('')
// });
myForm = this.fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
address: this.fb.group({
address1: [''],
address2: [''],
state: [''],
zip: [''],
}),
mobiles: this.fb.array([
this.fb.control('')
])
})
addAlias() {
this.mobiles.push(this.fb.control(''))
}
get mobiles() {
return this.myForm.get('mobiles') as FormArray
}
onSubmit() {
console.log(this.myForm.value);// 全部
// alert(this.myForm.controls['firstName'].value)
// alert(this.myForm.get('lastName').value) // 两种拿到当个值得方式
}
constructor(private fb: FormBuilder) {
}
ngOnInit(): void {
}
}
html
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<label>
FirstName:
<input type="text" formControlName="firstName">
</label> <br>
<label>
lastName:
<input type="text" formControlName="lastName">
</label> <br>
<div formGroupName="address">
<label>
address1:
<input type="text" formControlName="address1">
</label> <br>
<label>
address2:
<input type="text" formControlName="address2">
</label> <br>
<label>
State:
<input type="text" formControlName="state">
</label> <br>
<label>
zip:
<input type="text" formControlName="zip">
</label> <br>
</div>
<div formArrayName="mobiles">
<button (click)="addAlias()">增加</button>
<div *ngFor="let mob of mobiles.controls;let i=index">
<label>
Lable {{i}}:
<input type="text" [formControlName]="i">
</label>
</div>
</div>
<button type="submit" [disabled]="!myForm.valid">Submit</button>
</form>
添加自定义筛选
myForm = this.fb.group({
firstName: ['', Validators.required],
lastName: ['', [Validators.required, this.maxValida]],
/* 为 username 添加3项验证规则:
* 1.必填, 2.最大长度为10, 3.最小长度为3
* 其中第一个空字符串参数为表单的默认值
*/
'username': [ '', [
Validators.required,
Validators.maxLength(10),
Validators.minLength(3)
]]
})
maxValida(val) {
let len = val.value;
return len > 4 ? null : {error: true};
}
完整代码
html
<h3 class="text-center">注册</h3>
<form [formGroup]="registerForm" >
<div class="form-group">
<label for="username">用户名:</label>
<input formControlName="username"
type="text" id="username" #username
class="form-control" >
<div *ngIf="formErrors.username" class="showerr alert alert-danger" >{{ formErrors.username }}</div>
</div>
</form>
ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { validateRex } from './validate-register';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
// 定义表单
registerForm: FormGroup;
// 表单验证不通过时显示的错误消息
formErrors = {
username: ''
};
// 为每一项表单验证添加说明文字
validationMessage = {
'username': {
'minlength': '用户名长度最少为3个字符',
'maxlength': '用户名长度最多为10个字符',
'required': '请填写用户名',
'notdown': '用户名不能以下划线开头',
'only': '用户名只能包含数字、字母、下划线'
}
};
// 添加 fb 属性,用来创建表单
constructor(private fb: FormBuilder) { }
ngOnInit() {
// 初始化时构建表单
this.buildForm();
}
// 构建表单方法
buildForm(): void {
// 通过 formBuilder构建表单
this.registerForm = this.fb.group({
/* 为 username 添加3项验证规则:
* 1.必填, 2.最大长度为10, 3.最小长度为3, 4.不能以下划线开头, 5.只能包含数字、字母、下划线
* 其中第一个空字符串参数为表单的默认值
*/
'username': [ '', [
Validators.required,
Validators.maxLength(10),
Validators.minLength(3),
validateRex('notdown', /^(?!_)/),
validateRex('only', /^[1-9a-zA-Z_]+$/)
]]
});
// 每次表单数据发生变化的时候更新错误信息
this.registerForm.valueChanges
.subscribe(data => this.onValueChanged(data));
// 初始化错误信息
this.onValueChanged();
}
// 每次数据发生改变时触发此方法
onValueChanged(data?: any) {
// 如果表单不存在则返回
if (!this.registerForm) return;
// 获取当前的表单
const form = this.registerForm;
// 遍历错误消息对象
for (const field in this.formErrors) {
// 清空当前的错误消息
this.formErrors[field] = '';
// 获取当前表单的控件
const control = form.get(field);
// 当前表单存在此空间控件 && 此控件没有被修改 && 此控件验证不通过
if (control && control.dirty && !control.valid) {
// 获取验证不通过的控件名,为了获取更详细的不通过信息
const messages = this.validationMessage[field];
// 遍历当前控件的错误对象,获取到验证不通过的属性
for (const key in control.errors) {
// 把所有验证不通过项的说明文字拼接成错误消息
this.formErrors[field] += messages[key] + '
';
}
}
}
}
}
validate-register.ts
import { ValidatorFn, AbstractControl } from '@angular/forms';
export function validateRex(type: string, validateRex: RegExp): ValidatorFn {
return (control: AbstractControl): {[key: string]: any} => {
// 获取当前控件的内容
const str = control.value;
// 设置我们自定义的严重类型
const res = {};
res[type] = {str}
// 如果验证通过则返回 null 否则返回一个对象(包含我们自定义的属性)
return validateRex.test(str) ? null : res;
}
}
热模块更新
修改environmen文件
修改environments/environment.ts文件如下
export const environment = {
production: false,
hmr: true,
};
修改environments/environment.prod.ts文件如下
export const environment = {
production: true,
hmr: false,
};
运行的时候必须加--hmr
参数,这里暂时没有搞清楚为什么要加,因为根据代码的修改来看都是由environments文件决定是否需要启动hmr