[英]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.