typescript - Använda ngModel med anpassad komponent


Enkelt uttryckt vill jag binda min Switch-komponent tvåvägs till en boolean i en tjänst

Något sådant här:

@Component({
    selector: 'my-switch',
    template: '...'
})

export class Switch {
    @Input() state: Boolean

    toggle() {
        if (this.state) {
            this.state = false
        } else {
            this.state = true
        }
    }
}

@Injectable()

class export FooService {
    theBoolean: Boolean
}

@Component({
    selector: 'my-app',
    template: '<my-switch [(state)]="_foo.theBoolean"></my-switch>{{ _foo.theBoolean }}'
})

export class App {
    constructor(private _foo: FooService) {}
}

Så vad som bör hända här är att när strömbrytaren växlas, bör onChanges-händelsen i FooService utlösas, och vice versa.

Svar #1

För att tvåvägsbindning ska fungera behöver du deklarera en Output-händelse som kallas 'stateChange'

@Output stateChange: EventEmitter<Boolean>=new EventEmitter();

Sedan i din växlingsimplementation:

toggle() {
    if (this.state) {
        this.state = false;
    } else {
        this.state = true
    }
    this.stateChange.emit(this.state);
}

I din HTML-mall:

 [(state)]="model"

Är ekvivalent med:

 [state]="model"  (stateChange)="model=$event"

Där $event är argumentet som skickas till emit-metoden i EventEmitter. När tillståndet ändras, emitterar det stateChange-händelsen, vilket sedan uppdaterar modellen i föräldrakomponenten - och därmed håller modellerna synkroniserade

Svar #2

Du kan också prova följande

Definiera en variabel foo av typen FooService som @Input() i komponenten Switch och skicka foo-egenskapen av App till Switch-komponenten så som

@Component({
    selector: 'my-app',
    template: '<my-switch [foo]="_foo"></my-switch>{{ _foo.theBoolean }}'
})

export class App {
    constructor(private _foo: FooService) {}
}

export class Switch {
    @Input() foo: Foo

    toggle() {
        this.foo.theBoolean = !this.foo.theBoolean;
}

På det här sättet har du endast en instans av FooService som delas mellan App och Switch. Därför reflekteras alla ändringar på den (framkallade antingen av App eller Switch) på den andra komponenten.

Jag hoppas att detta hjälper