[英]Angular 2 observable subscription not triggering
我有一個訂閱可觀察不觸發的問題。
我有一個使用側面導航布局指令的布局,如下所示:
<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");
}
}
我創建了一個返回如下observable的服務:
@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");
});
}
}
現在我的問題是App組件中的訂閱不會觸發,但Home組件中的訂閱(路由器插座顯示的內容)會按預期觸發。
我在這里錯過了什么嗎?
我遵循了這個指南: https : //angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service
您的App和Home組件之間未共享相同的服務實例,因為您已將SidenavService
列為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
問題在於,與其他框架相反,Angular似乎並沒有強制Service
s默認為單例 。
因此,當您聲明自己的每個Component
都擁有自己的Service
實例時,您會遇到這種情況。 這導致每個實例具有不同的屬性( toggle
和toggleObs
)。 示意圖:
App - > SidenavService [ 實例A ]
首頁 - > SidenavService [ 實例B ]
您需要更改聲明以匹配單一服務 ,如Angular文檔中所述 。 這導致在所有Components
僅共享Service
的單個實例。 示意圖:
App - > SidenavService [ 實例A ]
首頁 - > SidenavService [ 實例A ]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.