angular9的学习(六)

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] + '\n';
         }
       }
     }
   }

 }

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

posted @ 2020-04-08 10:17  猫神甜辣酱  阅读(908)  评论(0编辑  收藏  举报