Custom checkbox input component styled with Switchery

前端 未结 1 724
闹比i
闹比i 2020-12-20 00:54

I\'m trying to create a custom checkbox component styled with Switchery that can be used in a form like any other componen

相关标签:
1条回答
  • 2020-12-20 01:29

    In fact you need to make your component "ngModel-compliant" but implementing a custom value accessor.

    Here is the way to do:

    @Component({
      selector: 'switchery-checkbox',
      template: `
        <input #checkbox type="checkbox" (change)="onChange($event.target.checked)" class="js-switch"/>
      `,
      (...)
    })
    export class SwitcheryComponent implements AfterViewInit, ControlValueAccessor {
      @Input() options: Switchery.Options = {};
      @Input() disabled:boolean = false;
      @ViewChild('checkbox') checkbox: any;
    
      value: boolean = false;
    
      onChange = (_) => {};
      onTouched = () => {};
    
      writeValue(value: any): void {
        this.value = value;
        this.setValue(this.value);
      }
    
      registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
      registerOnTouched(fn: () => void): void { this.onTouched = fn; }
    
      ngAfterViewInit() {
        this.switcher = new switchery(this.checkbox.nativeElement,
                  this.options);
        this.setValue(this.value);
        this.setDisabled(this.disabled);
      }
    
      ngOnChanges(changes: {[propName: string]: SimpleChange}) {
        if (changes && changes.disabled) {
          this.setDisabled(changes.disabled.currentValue);
        }
      }
    
      setValue(value) {
        if (this.switcher) {
          var element = this.switcher.element;
          element.checked = value
        }
      }
    
      setDisabled(value) {
        if (this.switcher) {
          if (value) {
            this.switcher.disable();
          } else {
            this.switcher.enable();
          }
        }
      }
    }
    

    Finally you need to register the value accessor into the providers of the component:

    const CUSTOM_VALUE_ACCESSOR = new Provider(
      NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => SwitcheryComponent), multi: true});
    
    @Component({
      selector: 'switchery-checkbox',
      template: `
        <input #checkbox type="checkbox" (change)="onChange($event.target.checked)" class="js-switch"/>
      `,
      providers: [ CUSTOM_VALUE_ACCESSOR ]
    })
    export class SwitcheryComponent implements AfterViewInit, ControlValueAccessor {
      (...)
    }
    

    This way you can use your directive this way:

    <switchery-checkbox [disabled]="disabled"
           [(ngModel)]="value" ngControl="cb"
           #cb="ngForm"></switchery-checkbox>
    

    See this plunkr: https://plnkr.co/edit/z1gAC5U0pgMSq0wicGHC?p=preview.

    See this article for more details (section "NgModel-compatible component"):

    • http://restlet.com/blog/2016/02/17/implementing-angular2-forms-beyond-basics-part-2/
    0 讨论(0)
提交回复
热议问题