无法在新选项卡中订阅Angular app中的可观察事件

无法在新选项卡中订阅Angular app中的可观察事件,angular,typescript,observable,angular-cli,Angular,Typescript,Observable,Angular Cli,我正在为一个web门户开发一个功能,让用户在将数据保存到数据库之前“预览”他们对数据所做的一些更改。我做了一个服务,有两个组件,一个发出更改事件,另一个(应该)监听,然后用预览更新自己 我希望预览在新选项卡中打开 我的服务是 @Injectable() export class PreviewService { private hub = new Subject<Hub>(); hubUpdated = this.hub.asObservable(); upd

我正在为一个web门户开发一个功能,让用户在将数据保存到数据库之前“预览”他们对数据所做的一些更改。我做了一个服务,有两个组件,一个发出更改事件,另一个(应该)监听,然后用预览更新自己

我希望预览在新选项卡中打开

我的服务是

@Injectable()
export class PreviewService {

   private hub = new Subject<Hub>();

   hubUpdated = this.hub.asObservable();

   updateHubPreview(hub: Hub) {
     this.hub.next(hub);
   }

   constructor() {
   }
}
我的预览组件是

constructor(private hubService: HubService, private route: ActivatedRoute, 
            private previewService: PreviewService) {

   this.hub = new Hub();
   previewService.hubUpdated.subscribe(value => {
      console.log("hello!");
      this.hub = value;
   });
 }

在新打开的窗口中,不会发生任何事情。

这可能是因为
主题仅在发出时才进行订阅,因此您在打开新窗口之前发出,因此在尝试订阅时,下一个
之前已经执行过,因此不会触发订阅。您可以使用始终订阅的
BehaviorSubject
,而不是
Subject

import {BehaviorSubject} from 'rxjs/BehaviorSubject';

private hub = new BehaviorSubject<Hub>(null);
从'rxjs/BehaviorSubject'导入{BehaviorSubject};
私有集线器=新行为主体(null);
见此:

摘录:

  • 行为主体需要初始值,因为它必须始终在订阅时返回值,即使它尚未收到
    next()

  • 常规可观察对象仅在收到onnext时触发

你是在山谷发射后订阅的。这对一门学科是行不通的


更改
private hub=新主题()到此
专用集线器=新的ReplaySubject(1)

我使用HTML5本地存储解决了这个问题。我有一门课:

export class StorageHelper {

    static write(key: string, item: any) {
       localStorage.setItem(key, JSON.stringify(item));
    }

   static read<T>(key: string): T {
      return <T>JSON.parse(localStorage.getItem(key));
   }
}
导出类StorageHelper{
静态写入(键:字符串,项:任意){
setItem(key,JSON.stringify(item));
}
静态读取(键:字符串):T{
返回JSON.parse(localStorage.getItem(key));
}
}

新选项卡在打开时只是从这个类请求一些数据,父选项卡已经存储了这些数据。这不是一个完美的解决方案,但它确实起到了作用。

谢谢!通过这个添加,我能够在组件打开新选项卡时获得某种消息,即组件正在读取服务调用。但是,任何进一步的更新,即进一步调用hub.next(newValue)都不会更新新窗口,因此我只能使用默认的null值。您在哪里将服务设置为提供者?它只在你的模块中提供,对吗?啊,等等。。。这是一个新标签。然后它将不起作用,您需要以某种方式同步这些,但不幸的是,我无法在这方面帮助您:(是的,该服务仅在我的app.module中提供。不用担心,我会勾选你的答案,因为它确实有帮助。我最终使用cookie解决了这个问题。每当我的发布者组件进行更改,写入cookie时,发布者只需每隔几秒钟读取一个cookie,并将其属性设置为收到的值。不是真的我很干净,但现在还可以
export class StorageHelper {

    static write(key: string, item: any) {
       localStorage.setItem(key, JSON.stringify(item));
    }

   static read<T>(key: string): T {
      return <T>JSON.parse(localStorage.getItem(key));
   }
}