我是Angular4的新手 . 很抱歉基本问题和我可怜的英语 . 我会尽力描述我的问题 .
我现在正在开发一个使用可观察服务来共享消息的网站 .
但我遇到了问题,这是我的example file structure . 和working Plunker .
我从“用户组件”收到了“标头组件”消息 .
Headers 组件:
import { Component, OnInit, OnDestroy} from '@angular/core';
import { Subscription } from 'rxjs/subscription';
import { SharedService } from "./sharedService";
@Component({
selector: 'shared-header',
template: `<div class="my-header">
<span>This is header </span>
<span class="right-align">Recieve Data:{{received}}</span>
</div>`,
})
export class HeaderComponent implements OnInit, OnDestroy{
private subscription: Subscription;
private received = "none";
constructor(private sharedService : SharedService) {}
ngOnInit(){
this.subscription = this.sharedService.shareAction$.subscribe(result => {
if(result){
this.received = result;
}
};
}
ngOnDestory(){
this.subscription.unsubscribe();
}
}
用户组件:
import { Component, OnInit, OnDestroy} from '@angular/core';
import { Subscription } from 'rxjs/subscription';
import { SharedService } from "./sharedService";
@Component({
selector: 'shared-header',
template: `<div class="my-header">
<span>This is header </span>
<span class="right-align">Recieve Data:{{received}}</span>
</div>`,
})
export class HeaderComponent implements OnInit, OnDestroy{
private subscription: Subscription;
private received = "none";
constructor(private sharedService : SharedService) {}
ngOnInit(){
this.subscription = this.sharedService.shareAction$.subscribe(result => {
if(result){
this.received = result;
}
};
}
ngOnDestory(){
this.subscription.unsubscribe();
}
}
和“Widget组件”从“产品组件”收到消息 .
小部件组件:
import { Component, OnInit, OnDestroy} from '@angular/core';
import { Subscription } from 'rxjs/subscription';
import { SharedService } from "./sharedService";
@Component({
selector: 'widget',
template: `<div>---Widget----</div>
<div>=={{productName}}==</div>`,
})
export class WidgetComponent implements OnInit, OnDestroy{
private productName = "none";
private subscription: Subscription;
constructor(private sharedService : SharedService) {}
ngOnInit(){
this.subscription = this.sharedService.shareAction$.subscribe(result => {
if(result){
this.productName = result;
}
};
}
ngOnDestory(){
this.subscription.unsubscribe();
}
}
产品组件:
import { Component, OnInit, OnDestroy} from '@angular/core';
import { SharedService } from "./sharedService";
@Component({
template: `<h4>This is ProductPage</h4>
<widget></widget>`,
})
export class ProductComponent implements OnInit, OnDestroy{
constructor(private sharedService : SharedService) {}
ngOnInit(){
this.sharedService.publishData('NIKE');
}
}
我创建了一个sharedService来处理可观察的服务 . 共享服务:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Subscription } from 'rxjs/subscription';
@Injectable()
export class SharedService {
private shareAction = new BehaviorSubject<any>(null);
shareAction$ = this.shareAction.asObservable()
sharedObject: object = {};
constructor() {}
publishData(data) {
console.log('publish------------------------------');
this.shareAction.next(data);
}
}
因此,当点击“用户页面”时, Headers 右侧的信息将显示“用户页面” . 点击“产品页面”时,小部件下方的信息将显示“NIKE” . 但同时, Headers 信息也变为“NIKE”,我不希望它发生 .
我知道我应该在组件销毁时取消订阅,但在这种情况下,Header永远不会被销毁 . 所以也许....我应该在“用户组件”销毁时取消订阅,并在“用户组件”初始化时再次订阅,但我不知道该怎么做,或者这个想法很糟糕 .
请给我一些指导,任何意见都会有所帮助 . 非常感谢 .
2 回答
我认为问题是你使用单个
shareAction$
来做太多事情 . 为什么不为 Headers 信息创建一个主题,为小部件创建另一个主题?此外,
shareAction$
过于宽泛:尝试给它一个更具体的名称,如headerTitle$
和currentProduct$
这样,Header组件和Widget组件都不需要知道何时订阅/取消订阅:它们只是在创建时订阅并在销毁时取消订阅 .
另外,考虑避免使用
any
作为类型:当你的应用程序足够大时,它会为你节省很多问题,因为如果有错误的话 .您是否需要通过服务全局共享
CurrentProduct
?如果你只在Product组件中使用它 - Widget组件也许它足够通过组件参数传递它 .使用angular 2内置机制(| async),它会自动取消订阅 .
some.component.ts:
some.component.html: