让angular表单更简单

extend 组件的使用

公共的方法,属性

@Component({
  selector: 'app-three',
  templateUrl: './three.component.html',
})
export class ThreeComponent {
  @Input() two = 'bbb';
  @Input() three = 'ccc';

  createMethod(val: any) {
    console.log(val);
  }
}

父组件继承, 跟html 没有关系

export class TwoComponent extends ThreeComponent implements OnInit {
  @Input('one') one: string = 'aaa'
  ngOnInit(): void {
  }
}

html

<div>{{one}}</div>
<div>{{two}}</div>
<div>{{three}}</div>
<button (click)="createMethod('xxx')">CLICK</button>

我们可以把公共的方法和属性写成一个组件, 然后其他组件需要这部分继承

自定义指令扩展UI组件

@Directive({
  // 组件
  selector: 'p-calendar',
  // 包含某个指令
  selector: 'p-calendar[defaultCalendar]',
  // 某个指令 排除某个指令
  selector: 'p-calendar:not([resetCalendar])',
})

我们写个ng-zorro的日期选择器

<nz-date-picker [(ngModel)]="date"
                nzFormat="yyyy/MM/dd HH:mm:ss"
                [nzShowTime]="false" [nzShowNow]="false"
                [nzShowToday]="false" [nzAllowClear]="false" [nzBorderless]="true"></nz-date-picker>

我们发现上面的属性太多了,我们可以通过自定义指令执行处理

@Directive({
  selector: 'nz-date-picker[appDateDefault]'
})
export class DateDefaultDirective {

  constructor(private defaultDate: NzDatePickerComponent) {
    this.defaultDate.nzBorderless = true;
    this.defaultDate.nzAllowClear = false;
    this.defaultDate.nzShowToday = false;
    this.defaultDate.nzShowNow = false;
    this.defaultDate.nzShowTime= false;
  }
}
<nz-date-picker [(ngModel)]="date" nzFormat="yyyy/MM/dd HH:mm:ss" appDateDefault></nz-date-picker>

当我们需要对项目的90%以上添加这个指令, 可以设置排除某个属性

@Directive({
  selector: 'nz-date-picker:not([appDateDefault])'
})

只要组件中不设置 appDateDefault 某符合, 类似于默认不写,也是符合要求的, 可用于修改组件的默认设置, 在这里基础上修复bug

指令修改子组件的表单

有时候我们纠结, 父组件修改子组件表单的信息, 我们看到常规来做,我们传入一个参数,然后做各种判断处理, 导致子组件的代码很累赘

@Component({
  selector: 'person',
  template: `
    <div [formGroup]="form">
      <div>
        <label>Name</label>
        <input type="text" formControlName="name" />
      </div>

      <div>
        <label>Contact info</label>
        <input type="text" formControlName="contactInfo" />
      </div>

      <div>
        <label>Allergies</label>
        <input type="text" formControlName="allergies" />
      </div>

      <strong>{{ form.valid ? 'valid' : 'invalid' }}</strong>
    </div>
  `,
})
export class PersonComponent {
  form = this.formBuilder.group({
    name: ['', Validators.required],
    contactInfo: [''],
    allergies: [''],
  })

  constructor(private formBuilder: FormBuilder) {}
}

给父级添加一个指令

@Directive({
  selector: 'person[stage-one]',
})
export class StageOneDirective {
  constructor(host: PersonComponent) {
    host.form.get('contactInfo').setValidators([Validators.required])
  }
}

添加另一个添加

@Directive({
  selector: 'person[stage-one]',
})
export class StageOneDirective {
  constructor(host: PersonComponent) {
    host.form.get('contactInfo').setValidators([Validators.required])
  }
}

然后使用的时候

<person></person>

<person stage-one></person>

<person stage-two></person>

自定义指令校验让Form表单更简单

校验器

import {Directive, Input} from '@angular/core';
import {AbstractControl, NG_VALIDATORS, ValidationErrors} from "@angular/forms";

@Directive({
  selector: '[appValidator]',
  providers: [{provide: NG_VALIDATORS, useExisting: ValidatorDirective, multi: true}],
})
export class ValidatorDirective {
  @Input() appValidator!: (control: AbstractControl) => ValidationErrors | null;

  validate(control: AbstractControl): ValidationErrors | null {
    return this.appValidator(control);
  }
}

组件

<input type="text" [appValidator]="scoreValidator" [(ngModel)]="date" #score="ngModel"/>
<app-has-error [control]="score.control"></app-has-error>
export class TwoComponent implements OnInit {
  date = null
  scoreValidator = (control: AbstractControl): ValidationErrors | null => {
    const {dirty, touched, value} = control;
    // 这个是为了默认默认的时候触发
    if ((!!dirty || !!touched) && !value) {
      return {required: true}
    }
    if (value?.length > 10) {
      return {maxScore: 10};
    }
    return null;
  };
}

app-has-error

  @Input() control!: AbstractControl

这样我就可以做一些报错处理

posted @ 2022-03-09 13:37  猫神甜辣酱  阅读(118)  评论(0编辑  收藏  举报