自定义表单控件(基于nz-checkbox)

1.在自定义的表单组件中,需要实现ControlValueAccessor接口,这个接口的作用有两个:

  • 将form模型中的值映射到视图中
  • 当视图发生变化时,通知form directives或form controls

在自定义的表单组件中实现ControlValueAccessor接口的方式是将其注册为NG_VALUE_ACCESSOR:

	providers: [
	    {
	      provide: NG_VALUE_ACCESSOR,
	      useExisting: forwardRef(() => KyCheckboxComponent ),
	      multi: true,
	    },
    ],

另外接口ControlValueAccessor中有三个必须实现的的方法:

  1. writeValue(obj:any):将表单模型的中的值写入视图中
	 // model view -> view value
     writeValue(value: any): void {
       this.kyChecked = value;
     }
  1. registerOnChange(fn:any):用于注册在视图中某些内容发生改变时应该调用的的处理处理程序。它获取一个函数,告诉其他表单指令和表单控件更新其值。
	 // view value ->model value
     registerOnChange(fn: any): void {
       this.onModelChange = fn;
     }
  1. registerOnTouched(fn:any):它专门为空间接收触摸事件时注册一个处理程序。
	registerOnTouched(fn: any): void {
	    this._onTouched = fn;
    }
  1. setDisabledState?(isDisabled:boolean):这是一个可选方法,设置自定义表单的状态
	setDisabledState(isDisabled: boolean): void {
	    this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
    }

您通过以上操作,便可以以将自定义表单控件无缝地集成到模板驱动或响应表单中,就像它是本地表单一样!

注:writeValue和registerOnChange是实现ngModel双向绑定的关键(具体可参看ky-checkbox组件)

以下为ky-checkbox组件代码:

	import {
	  Component,
	  Input,
	  forwardRef,
	  ViewEncapsulation,
	  Output,
	  EventEmitter,
	} from '@angular/core';
	import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
	import { InputBoolean } from 'ng-zorro-antd';
	
	@Component({
	  selector: 'ky-checkbox',
	  template: `
	    
	  `,
	  styles: [
	    `
	      label {
	        display: block;
	        padding: 5px 0;
	      }
	
	      .mobile .ant-checkbox-wrapper.checked {
	        background: #e9eeff;
	        border-color: #7490e7;
	      }
	    `,
	  ],
	  encapsulation: ViewEncapsulation.None,
	  host: {
	    '[class.ky-checkbox-wrapper]': 'true',
	  },
	  providers: [
	    {
	      provide: NG_VALUE_ACCESSOR,
	      useExisting: forwardRef(() => KyCheckboxComponent),
	      multi: true,
	    },
	  ],
	})
	export class KyCheckboxComponent implements ControlValueAccessor {
	  @Input() mode: 'web' | 'mobile' = 'web';
	  @Input() @InputBoolean() kyChecked = false;
	  @Input() @InputBoolean() kyDisabled = false;
	
	  @Output() kyCheckedChange: EventEmitter<boolean> = new EventEmitter();
	
	  onModelChange = (T) => {};
	
	  // model view -> view value
	  writeValue(value: any): void {
	    this.kyChecked = value;
	  }
	
	  // view value ->model value
	  registerOnChange(fn: any): void {
	    this.onModelChange = fn;
	  }
	
	  registerOnTouched(): void {}
	
	  setDisabledState(isDisabled: boolean): void {}
	
	  onCheckChange(newValue: boolean): void {
	    this.kyChecked = newValue;
	    this.onModelChange(newValue);
	
	    this.kyCheckedChange.emit(newValue);
	  }
	}

你可能感兴趣的:(前端,angular,NG-ZORRO,angular)