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
}
}
をあなたはなぜそれそれはだ、サービスのSidebarContentComponentを設定しないでくださいsそれは未定義ですそれをコンストラクタに入れても機能しません。SidebarContentComponentはおそらく1つしかありません。 – Ploppy
デザインが間違っています。サービスはコンポーネントに注入されます。逆もありません。コンポーネントをサービスに「注入」することはできません。技術的には、コンポーネントは注入可能なクラスなのでできますが、ここでは正しく動作しません。 – estus
@estus私は、この状況でそれを行う正しい方法は、rxjs/subjectを使用して、サービスがそのメソッド呼び出しをそのサブスクライバに伝播させることだと思います。 – Ploppy