我想從我的共享服務調用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();
}
}
從另一個組件調用開放方法:
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,這就是爲什麼它小號並且它是未定義的。將它放在構造函數中不起作用:它可以是任何SidebarContentComponent,即使您可能只有一個。 – Ploppy
設計是錯誤的。服務被注入組件,反之亦然。你不能將一個組件注入到服務中。從技術上講,你可以這樣做,因爲組件是可注入類,但它不能正常工作,就像我們在這裏看到的那樣。 – estus
@estus我認爲在這種情況下正確的做法是使用rxjs /主題並讓服務將方法調用傳播給它的訂閱者。 – Ploppy