2016-05-01 47 views
2

簡單地說,我想兩路我的開關組件使用ngModel與自定義組件

像這樣綁定到一個布爾值,在服務:

@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) {} 
} 

那麼應該在這裏出現的情況是,當切換開關時,FooService中的onChanges事件應該觸發,反之亦然。

+0

對於雙向綁定,您需要使用EventEmitter公開一個stateChange輸出事件。 – pixelbits

+0

你可以發佈這個作爲一個示例代碼的答案嗎? –

回答

3

對於雙向綁定工作,你需要聲明稱爲輸出事件 'stateChange'

@Output stateChange: EventEmitter<Boolean>=new EventEmitter(); 
在你撥動實現

然後:

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

在HTML模板:

[(state)]="model" 

相當於:

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

其中$ event是傳遞給EventEmitter的emit方法的參數。每當狀態發生變化時,會發出stateChange事件,然後更新模型中的父組件 - 從而保持模型同步

+0

末尾的「更改」後綴是否重要?或者它可以是任何東西? –

+0

根據打字稿,您頂部的代碼似乎也是無效的。 –

+0

已修復,應該是一項任務 – pixelbits

0

您也可以嘗試以下

定義類型FooService接口作爲@input的變量foo的()在組件開關和應用的富財產傳給開關元件su作爲

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

這種方式你FooService接口只有一個實例應用程序和交換機之間共享。因此,其上的任何更改(由App或Switch採購)都反映在另一個組件上。

我希望這有助於

0

你也可以看到,你可以很容易地實現自定義組件,爲ngModel/ngControl兼容通過利用一個自定義的值訪問。這樣,您就可以使用ngModelngControl/ngFormControl由表單(驗證值)的一部分,使你的組件是這樣的:

<my-switch [(ngModel)]="_foo.theBoolean" 
      #ctrl="ngModel" ngControl="switch"></my-switch> 

這裏是實現這個方式:

const SWITCH_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => Switch), multi: true}); 

@Component({ 
    selector: 'my-switch', 
    template: '...' 
}) 
export class Switch implements ControlValueAccessor { 
    state: boolean; 

    onChange = (_) => {}; 
    onTouched =() => {}; 

    writeValue(value: any): void { 
    this.state = value; 
    } 

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

    registerOnChange(fn: (_: any) => void): void { this.onChange = fn; } 
    registerOnTouched(fn:() => void): void { this.onTouched = fn; } 
} 

見本鏈接瞭解詳情: