2017-02-03 3 views
0

ngModelChangeとEventEmitterを使用して、選択ボックスコンポーネントの値で特定のタスクを実行します。しかし、emit()を実行するとすぐに、選択ボックスのテキストが消えます。エミッタを取り除くとすぐに、選択ボックスが完全に動作します。完全なコードはここにあります。Angular2では、イベントエミッタを使用しているときに、選択ボックスのテキストが消えます。

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; 
 
import { ContributorApi } from '../../../services/ContributorApi'; 
 
import { Contributor } from '../../../models/model.Contributor'; 
 

 
@Component({ 
 
    selector: 'module-builder-instructor-box', 
 
    template: ` 
 
    <div class="inline-form-control-wrapper required-input-field margin-bottom-15"> 
 
     <select [ngModel]="selectedItem" (ngModelChange)="onChange($event)" class="form-control medium-length gradient-bg font-medium"> 
 
     <option disabled> Select Instructor</option> 
 
     <option *ngFor="let contributor of contributors" 
 
      [ngValue]="contributor" 
 
     >{{contributor.first_name}} {{contributor.last_name}}</option> 
 
     </select> 
 
    </div> 
 
    ` 
 
}) 
 
export default class ModuleBuilderInstructorSelect implements OnInit { 
 
    @Input() instructorIndex: number; 
 
    @Output() setInstructor = new EventEmitter<any>(); 
 
    contributors: Contributor[]; 
 
    selectedItem: Contributor; 
 

 
    constructor(private contributorApi: ContributorApi) { 
 
    } 
 

 
    ngOnInit() { 
 
    this.contributorApi.getContributors().subscribe(
 
     res => { 
 
     this.contributors = res; 
 
     }, 
 
     error => { 
 
     console.log(error); 
 
     } 
 
    ); 
 
    } 
 

 
    onChange(value: Contributor) { 
 
    this.selectedItem = value; 
 
    this.setInstructor.emit({index: this.instructorIndex, id: this.selectedItem.id}); 
 
    console.log(this.selectedItem); 
 
    } 
 
}

+0

選択時にオプションを変更するとコンソールログを表示できますか?私は確かではありませんが、ngModelChangeの$ event_はコントリビュータオブジェクトではありません –

+0

$ eventはどのタイプのオブジェクトでもかまいません。この場合、それはコントリビュータオブジェクトでした。問題を見つけた方法あなたの助けをありがとう –

答えて

0

あなたが EventEmiiterで実装するための正しい方法を使用して確認してくださいparentComponentにでこれをインポートするときに実際にこのコードは、罰金

を進めています。たとえば何をしようとする、その後

<module-builder-instructor-box (setInstructor)="ParentFuncName($event)"></module-builder-instructor-box> 

とParent.component.ts

private ParentFuncName(value: any) { 
    // do your code here 
    } 
+0

あなたは正しく働いていた。私は実際にselectboxコンポーネントの数を設定するために使用されるngForで使用される配列を変更していました。これは問題を引き起こしていた –

0

には、カスタム入力コンポーネントです。このための良い習慣は、あなたのコンポーネントを呼び出すときに、[(ngModel)]を使用することができますので、ControlValueAccessorを実装することであり、それは角フォームとうまく統合し、必要な場合は、外部からの変更コールバックを提供することができます。

<module-builder-instructor-box [(ngModel)]="myVariable" (change)="handleChange($event)"></module-builder-instructor-box> 

私は実際に問題を発見http://almerosteyn.com/2016/04/linkup-custom-control-to-ngcontrol-ngmodel

+0

うーん、追加する余分なもののように思える。とにかく私のために働いています。どうもありがとう –

0

:ここ

import { Component, forwardRef } from '@angular/core'; 
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms'; 

const noop =() => { }; 

@Component({ 
    selector: 'module-builder-instructor-box', 
    template: `...`, 
    providers: [ 
    { 
     provide: NG_VALUE_ACCESSOR, 
     useExisting: forwardRef(() => FibaInputTextComponent), 
     multi: true 
    } 
], 
}) 
export default class ModuleBuilderInstructorSelect implements ControlValueAccessor { 
    //The internal data model 
    private innerValue: any = ''; 

    //Placeholders for the callbacks which are later providesd 
    //by the Control Value Accessor 
    private onTouchedCallback:() => void = noop; 
    private onChangeCallback: (_: any) => void = noop; 

    //get accessor 
    get value(): any { 
     return this.innerValue; 
    }; 

    //set accessor including call the onchange callback 
    set value(v: any) { 

     // Put what you want to do when selected value changes here 

     if (v !== this.innerValue) { 
      this.innerValue = v; 
      this.onChangeCallback(v); 
     } 
    } 

    //Set touched on blur 
    onBlur() { 
     this.onTouchedCallback(); 
    } 

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

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

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

完全なチュートリアル:あなたのコンポーネントは次のようになります。エミッタ自体とは何の関係もありませんでした。 エミッタによって実行されていた関数では、親コンポーネント内部のngForで使用される配列を変更していました。これは子コンポーネントをリセットしていたため、選択ボックスをリセットしていました。

関連する問題