2016-04-12 9 views
2

Ich versuche, eine benutzerdefinierte Kontrollkästchen Komponente mit Switchery Stil, die in einer Form wie jede andere <input type="checkbox" ... /> Komponente verwendet werden kann.Benutzerdefinierte Kontrollkästchen Eingangskomponente mit Switchery

Der Code habe ich jetzt kümmert sich um das Styling:

import {Component,ViewChild,AfterViewInit,Input} from 'angular2/core'; 
import switchery from 'switchery'; 

@Component({ 
    selector: 'switchery-checkbox', 
    template: `<input #checkbox type="checkbox" class="js-switch"/>`, 
}) 
export class SwitcheryComponent implements AfterViewInit { 
    @Input() options: Switchery.Options = {}; 
    @ViewChild('checkbox') checkbox: any; 
    ngAfterViewInit() { 
    new switchery(this.checkbox.nativeElement, 
        this.options); 
    } 
} 

Was muss ich noch hinzufügen können, um es wie in den folgenden Code in einer Vorlage benutzen? Es sollte idealerweise die gesamte Funktionalität von <input type="checkbox" /> implementieren.

<switchery-checkbox 
    [(ngModel)]="model.onOrOff" 
    ngControl="onOrOff" 
    [disabled]="disabledCondition" 
    ... > 
</switchery-checkbox> 

Antwort

3

In der Tat müssen Sie die Komponente "ngModel-compliant", aber die Implementierung eines benutzerdefinierten Wert Accessor machen.

Hier ist die Art und Weise zu tun:

@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(); 
     } 
    } 
    } 
} 

Schließlich müssen Sie den Wert Accessor in die providers der Komponente registrieren:

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 { 
    (...) 
} 

So können Sie Ihre Richtlinie auf diese Weise verwenden können:

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

Siehe diese Plunkr: https://plnkr.co/edit/z1gAC5U0pgMSq0wicGHC?p=preview.

in diesem Artikel für weitere Details (siehe Abschnitt "NgModel-kompatible Komponente"):

Verwandte Themen