2016-10-12 5 views
2

<select>要素のカスタムフォームコントロールコンポーネントを作成しようとしています(これはカスタムフォームコントロールを作成する最も革新的な方法ではありませんが、これはテスト用です)。私はチュートリアル@http://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.htmlに従っています。角型2でカスタムフォームコントロールを作成

私が目指しているのは、<select-box>コンポーネントから値が選択されるまでサブミットボタンを無効にすることですが、値が変わらないのでカスタムフォームコントロールを正しく接続しているとは思いません別の値を選択したり、検証作業が行われたりしていない場合(検証=ただカスタムコンポーネントのrequired HTML属性)

私が今までに持っているものについては以下を参照してください。あるいは、プランターはhttp://plnkr.co/edit/TAxDyb8sHg158dXmyfwr?p=previewにあります。

ありがとうございます!ここで

主成分

import {Component, NgModule} from '@angular/core'; 
import {BrowserModule} from '@angular/platform-browser'; 
import {SelectBoxComponent} from "./select-box.component"; 
import {FormsModule} from "@angular/forms"; 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 
     <form #form="ngForm" (ngSubmit)="log(form.value)"> 
     <select-box name="someValue" [ngModel]="someValue" required></select-box> 
     <br> 
     <button type="submit" [disabled]="!form.valid">Submit</button> 
     </form> 
     <br> 
     {{ form.value | json }} 
    </div> 
    `, 
}) 
export class App { 
    name:string; 
    someValue: any = 1; 

    log(str) { 
    console.log(str); 
    } 
} 

@NgModule({ 
    imports: [ BrowserModule, FormsModule ], 
    declarations: [ App, SelectBoxComponent ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

選択ボックスコンポーネント

import { Component, forwardRef, Input } from "@angular/core"; 
import { SelectControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"; 

@Component({ 
    selector: "select-box", 
    template: ` 
    <select onchange="onChanged(event.target.value)" [ngModel]="ngModel"> 
     <option disabled selected value></option> 
     <option value="1">1</option> 
     <option value="2">2</option> 
    </select> 
    `, 
    providers: [ 
    { 
     provide: NG_VALUE_ACCESSOR, 
     useExisting: forwardRef(() => SelectBoxComponent), 
     multi: true, 
    } 
    ], 
}) 

export class SelectBoxComponent implements SelectControlValueAccessor { 
    @Input() ngModel: any; 

    onChanged(value) { 
    this.ngModel = value; 
    this.propagateChange(value); 
    } 

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

    propagateChange = (_: any) => {}; 

    registerOnChange(fn) { 
    this.propagateChange = fn; 
    } 

    registerOnTouched() {} 
} 
+0

あなたの質問に答えるために必要なすべてのコンテンツをインラインでインラインで送信しないでください。 – gdoron

+0

@gdoron確かに、質問に追加しました – giwook

+0

'window [" onChanged "] = this.onChanged.bind(this);'とは何ですか?あなたが知っていることは、ページ上に2つを持つことができないということですね。 –

答えて

4

あなたのコンポーネントのための修正:.tshttp://plnkr.co/edit/69SGnjYGBWhC4tEezc1G?p=preview

<select [(ngModel)]="selectValue"> 
    <option disabled selected value></option> 
    <option value="1">1</option> 
    <option value="2">2</option> 
</select> 

export class SelectBoxComponent implements ControlValueAccessor { 
    private _selectValue: any = ''; 
    private _onTouchedCallback:() => {}; 
    private _onChangeCallback: (_:any) => {}; 

    get selectValue(): any { 
    return this._selectValue; 
    } 
    set selectValue(value: any) { 
    if (value !== this._selectValue) { 
     this._inputValue = value; 
     this._onChangeCallback(value); 
    } 

    this.hasValue = (value != null && value.length > 0) 

    this._onTouchedCallback(); 

    } 



    //From ControlValueAccessor interface 
    writeValue(value: any) { 
    this._selectValue = value; 
    } 

    //From ControlValueAccessor interface 
    registerOnChange(fn: any) { 
    this._onChangeCallback = fn; 
    } 

    //From ControlValueAccessor interface 
    registerOnTouched(fn: any) { 
    this._onTouchedCallback = fn; 
    } 
} 

選択したコンポーネントには、いくつかの間違いがあります。

  1. モデルを正しくバインドしていません。 getter/setterを追加すると、変更を追跡して通知することができます。this._onChangeCallbackthis._onTouchedCallback();
  2. registerOnTouchedイベントを登録してトリガーする必要があります。そうすれば、モデルはdirtyになり、フォームは有効/無効の変更を検出できます。
+0

私は最初に持っていた 'SelectControlValueAccessor'とは対照的に、' ControlValueAccessor'を使用していることに気付きました。私は、それぞれのタイプの入力を対応する値アクセサで使用する必要があるという印象を受けましたが、これは間違っているか、私が気付いていない注意点がありますか? – giwook

関連する問題