2017-05-26 10 views
0

sidenavコンポーネントのメソッドopen()を共有サービスから呼び出したいとします。私がコンポーネントから直接メソッドを呼び出すと、正常に動作しています。共有サービスからコンポーネントのメソッドを呼び出す

ERROR TypeError: Cannot read property 'open' of undefined

Sidenavコンポーネント:

import { MdSidenav } from '@angular/material'; 
import { Component, OnInit, ViewChild } from '@angular/core'; 

@Component({ 
    selector: 'app-sidebar-content', 
    template: ` 
    <md-sidenav-container class="container"> 
    <md-sidenav #sidenav class="sidenav"> 
     Jolly good! 
    </md-sidenav> 

    <app-main-content></app-main-content> 

    </md-sidenav-container> 
    `, 
    styleUrls: ['./sidebar-content.component.css'] 
}) 
export class SidebarContentComponent implements OnInit { 

    @ViewChild('sidenav') el: MdSidenav; 

    constructor() { } 

    ngOnInit() { 

    } 

    openSideNav() { 
    this.el.open();  
    } 

} 

共有サービス:

import { SidebarContentComponent } from './../content/sidebar-content/sidebar-content.component'; 
import { Injectable } from '@angular/core'; 


@Injectable() 
export class SharedService { 

    constructor(private sc: SidebarContentComponent) { } 

    openSidenav() { 
    this.sc.openSideNav(); 
    } 

} 

しかし、すぐに、私は共有サービスから同じメソッドを呼び出すように私は、エラーメッセージが表示されました別のコンポーネントからopenメソッドを呼び出す:

import { SharedService } from './../../services/shared.service'; 
import { Component, OnInit } from '@angular/core'; 

import { SidebarContentComponent } from './../sidebar-content/sidebar-content.component'; 

@Component({ 
    selector: 'app-main-content', 
    templateUrl: ` 
    <div class="sidenav-content"> 
     <app-toolbar></app-toolbar> 
     <button md-button (click)="open()"> 
     Open sidenav 
     </button> 
     <button md-button (click)="openWithService()"> 
     Open sidenav with service 
     </button> 
    </div> 
    `, 
    styleUrls: ['./main-content.component.css'] 
}) 
export class MainContentComponent implements OnInit { 

    constructor(private sc: SidebarContentComponent, private ss: SharedService) { } 

    ngOnInit() { 
    } 

    open() { 
    this.sc.openSideNav(); 
    // Works fine 
    } 

    openWithService() { 
    this.ss.openSidenav(); 
    // Throws an error 
    // ERROR TypeError: Cannot read property 'open' of undefined 
    } 

} 
+0

をあなたはなぜそれそれはだ、サービスのSidebarContentComponentを設定しないでくださいsそれは未定義ですそれをコンストラクタに入れても機能しません。SidebarContentComponentはおそらく1つしかありません。 – Ploppy

+1

デザインが間違っています。サービスはコンポーネントに注入されます。逆もありません。コンポーネントをサービスに「注入」することはできません。技術的には、コンポーネントは注入可能なクラスなのでできますが、ここでは正しく動作しません。 – estus

+0

@estus私は、この状況でそれを行う正しい方法は、rxjs/subjectを使用して、サービスがそのメソッド呼び出しをそのサブスクライバに伝播させることだと思います。 – Ploppy

答えて

1

サービスのSidebarContentComponentを設定していません。あなたはそれを行うことはできますが、適切な方法はrxjs/Subjectを使うことです。

これはそれを行う必要があります。

SharedService

import { Subject } from 'rxjs/Subject'; // don't forget to import it! 

public open$: Subject<any> = new Subject(); 

SidenavComponent

this.sharedService.open$.subscribe(() => this.openSideNav()); 

AnyComponent

this.sharedService.open$.next(); 
+0

「Uncaught Error:SidebarContentComponentのすべてのパラメータを解決できません:(?)」というエラーが表示される理由はわかりません。エラー – Gabriel

+0

私のコードとは関係ないと思います。このエラーはどこにありますか? – Ploppy

+0

これはSidenavComponentにあります。明確にするために、Sidenavコンポーネントにサービスを注入する必要があります。その後、ngOnInitフックのサブジェクトに登録する必要があります。 – Gabriel

関連する問題