2016-06-25 50 views
11

我遇到一個觀察問題,無法觸發。Angular 2可觀察的訂閱不觸發

我使用看起來像這樣一邊導航佈局指令佈局:

<md-sidenav-layout class="nav-bar"> 


    <md-sidenav #start> 
     <nav> 
      <a [routerLink]="['/home']">Home</a> 
     </nav> 
     <button md-button (click)="start.close()">Close</button> 
    </md-sidenav> 

    <router-outlet></router-outlet> 

</md-sidenav-layout> 

我需要做的是開放路由器出口正在顯示該組件的側導航。

一個這樣的組件可能是這樣的:

@Component({ 

    providers: [SidenavService, MdIconRegistry], 
    directives: [MdIcon], 
    templateUrl: `<md-icon (click)="toggleSidenav()">menu</md-icon>`, 
    styleUrls: ["./home.component.scss"] 
}) 

export class Home { 

    myColor: string; 

    constructor(private sidenavService: SidenavService) { 
     this.myColor = "primary"; 

     this.sidenavService.getSidenavObs().subscribe(state => {console.log("state change")}); 
    } 


    toggleSidenav() { 

     this.sidenavService.toggleSidenav("open"); 
    } 

} 

我創建了返回可觀察到的這樣一種服務:

@Injectable() 
export class SidenavService { 

    private toggle = new Subject<string>(); 
    private toggleObs = this.toggle.asObservable(); 

    getSidenavObs() { 
     return this.toggleObs; 
    } 

    toggleSidenav(state: string) { 
     this.toggle.next(state); 
    } 

} 

最後父類的代碼(即與所屬側導航佈局HTML):

@Component({ 
    providers: [MdSidenav, SidenavService], 
    directives: [ROUTER_DIRECTIVES, MD_SIDENAV_DIRECTIVES, MD_BUTTON_DIRECTIVES], 
    selector: "app", 
    templateUrl: "app.html", 
    styleUrls: ["./app.scss"], 
}) 

export class App { 

    subscription: Subscription; 

    constructor(private sidenavService: SidenavService, private sidenav: MdSidenav) { 
    this.subscription = sidenavService.getSidenavObs().subscribe(status => { 
     console.log("state change"); 
     sidenav.open(); 
    }, error => { 
     console.log(error); 
    },() => { 
     console.log("completed"); 
    }); 
    } 
} 

現在我的問題是訂閱但是,應用程序組件不會觸發Home組件中的訂閱(這是路由器插座顯示的內容)按預期觸發。

我在這裏錯過了什麼嗎?

我遵循這個指南:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

回答

49

相同的服務實例未在您的應用程序和家庭組件共享,因爲您列出SidenavService作爲兩個供應商。

當您在組件裝飾器的providers條目中定義服務提供者時,該服務隨後將作爲單例用於該組件及其所有子組件,這意味着將使用該服務的相同實例。

如果您重新定義子組件中的提供程序,它將創建一個新的服務實例,並且不再與其父/祖先共享相同的服務實例。

如果您在App和Home組件中使用SidenavService並且需要相同的實例,則應該只在App組件中提供它,並將其從Home的providers條目中刪除。

有關DI的更多信息,有以下鏈接讀: https://angular.io/docs/ts/latest/guide/dependency-injection.html https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

+0

非常感謝!這解決了我的問題。 – mda144

+1

謝謝Michael! – Leibniz

+0

謝謝邁克爾!!你救了我 – bews99