2017-08-16 21 views
1

他のコンポーネントから呼び出したいToastComponentというトースト通知コンポーネントがあります。私は、someSaveMethod()メソッドを呼び出すことで角4 - @ViewChildコンポーネントが定義されていません

export class UserManagementComponent implements OnInit { 

    @ViewChild(ToastComponent) toast: ToastComponent; 

    constructor() {} 

    someSaveMethod() { 
    this.toast.showToast() // throws error below 
    } 
} 

ToastComponent

export class ToastComponent implements OnInit { 

    constructor() {} 

    showToast() { 
    // some code 
    } 
} 

app.component.html

<llqa-main-container> 
    <llqa-header></llqa-header> 
    <div class="content-container"> 
    <main class="content-area"> 
     <llqa-toast></llqa-toast> <!-- ToastComponent which I want to call --> 
     <router-outlet></router-outlet> 
    </main> 
    </div> 
</llqa-main-container> 

UserManagementComponent<router-outlet>内である私はこのようにそれを実装しましたtoastが定義されていないというエラーが表示されます。

<llqa-toast></llqa-toast>app.component.htmlから取り出してuser-management.component.htmlの上に置いてもうまくいきますが、すべてのコンポーネントに入れなければなりません。これをどのように機能させることができますか?

+2

? 'someSaveMethod'の呼び出しの前に' ToastComponent'のコンストラクタが呼び出されたかどうか 'console.log()'ステートメントで調べてみてください。 –

答えて

3

あなたのケースでは、ToastComponentが祖父母(AppComponent)で使用されているため、このエラーが発生しています。このエラーを回避する1つの方法は、一部の共有サービスで定義されているSubjectを使用することです。私はトースト通知を表示するために私のプロジェクトでこのアプローチを使用しています。ここではあなたがそれを行うことができる方法である。


があなたの<llqa-toast></llqa-toast>app.component.htmlにしてください。

基本的にイベントを発行し、そのイベントにサブスクライブするサービスをToastComponentで定義します。例えば、

UtilityService:

import { Injectable } from '@angular/core'; 
import { Subject } from 'rxjs'; 

@Injectable() 
export class UtilityService { 

    public OnShowToast = new Subject<boolean>(); 

    public showToast(): void { 
     this.OnShowToast.next(true); 
    } 
} 

あなたAppModuleプロバイダーにこのサービスを注入する必要があります。今度はのsubscribeからOnShowToastまでのイベントです。

ToastComponent:今

import { UtilityService } from './path/to/the/utility.service'; 
export class ToastComponent implements OnInit { 

    constructor(private readonly utilityService: UtilityService) { } 

    ngOnInit() { 
    this.utilityService.OnShowToast.subscribe(value => 
     { 
      this.showToast(); 
     }); 
    } 

    private showToast() { 
    // some code 
    } 
} 

、あなたが望む任意のコンポーネントからUtilityServiceshowToast()メソッドを呼び出すことができます。例えば、

UserManagementComponent `と呼ばれてsomeSaveMethod`れ

export class UserManagementComponent implements OnInit { 

    // You dont need this now 
    // @ViewChild(ToastComponent) toast: ToastComponent; 

    constructor(private readonly utilityService: UtilityService) {} 

    someSaveMethod() { 
    this.utilityService.showToast(); 
    } 
} 
+1

'EventEmitter'はサービスで使用されるはずです。 'Observable'または' Subject'も同じです。 'EventEmitter'は' @Output() 'に** **のみ使用されるはずです。 –

+0

@GünterZöchbauer私のサービスで問題なく動作していたので、それを知らなかった。ありがとう。代わりに 'Subject'を使うように私のコードを更新してください。 – Faisal

+1

'EventEmitter'が単に' Subject'(AFAIR)を拡張しているので、Angularチームはこれを '@Output()'でも動作するカスタム実装に変更することができますが、 Output()は、EventEmitterが使用されている唯一のものです。 –

関連する問題