Fork Me On Github

默认的 ngModel 的实现方式为

@Component({
  selector: 'app-switch',
  template: `
    <div (click)="tapAdd()">{{ value }}</div>
  `,
  styleUrls: ['./switch.component.scss'],
})
export class SwitchComponent { 

    @Input() value = 0;
    @Output() valueChange: EventEmitter<number> = new EventEmitter();

    public tapAdd() {
        this.valueChange.emit(++ this.value);
    }
}

使用

<app-switch [(ngModel)]="value"></app-switch>

但这种方式是不支持 formControlName 绑定的

会提示No value accessor for form control with name: 错误

修改代码

因此必须换种方式

@Component({
    selector: 'app-switch',
    template: `
        <div (click)="tapAdd()">{{ value }}</div>
    `,
    styleUrls: ['./switch.component.scss'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => SwitchComponent),
            multi: true
        }
    ]
})
export class SwitchComponent implements ControlValueAccessor { 

    public value = 0;
    public disable = false;

    onChange: any = () => { };
    onTouch: any = () => { };

    public tapAdd() {
        if (this.disable) {
            return;
        }
        this.onChange(++ this.value);
    }

    writeValue(obj: any): void {
        this.value = obj;
    }
    registerOnChange(fn: any): void {
        this.onChange = fn;
    }
    registerOnTouched(fn: any): void {
        this.onTouch = fn;
    }
    setDisabledState?(isDisabled: boolean): void {
        this.disable = isDisabled;
    }
}

现在可以就支持两种方式了

<app-switch [(ngModel)]="value"></app-switch>

<app-switch formControlName="value"></app-switch>

例子

Example with Input

Example with Lazy Loaded Input

Example with Button

点击查看全文
标签: angular
0 15 0