我正在开发一个门户网站功能,供用户预览"在将数据保存到数据库之前,他们对数据进行了一些更改。我已经制作了一个服务,并且有两个组件,一个发出更改事件,另一个组件(应该)监听,然后通过预览更新自己。
我希望在新标签页中打开预览。
我的服务是
@Injectable()
export class PreviewService {
private hub = new Subject<Hub>();
hubUpdated = this.hub.asObservable();
updateHubPreview(hub: Hub) {
this.hub.next(hub);
}
constructor() {
}
}
我的发射组件按
发出事件emitChange(): void {
this.previewService.updateHubPreview(this.hub);
window.open(`hubs/preview/mock/${this.hub.id}`);
// I also tried [routerLink=...] target="_blank" in the template
}
我的预览组件是
constructor(private hubService: HubService, private route: ActivatedRoute,
private previewService: PreviewService) {
this.hub = new Hub();
previewService.hubUpdated.subscribe(value => {
console.log("hello!");
this.hub = value;
});
}
在新打开的窗口中,没有任何反应。
答案 0 :(得分:3)
这可能是因为Subject
只在发出发射时才订阅,所以在打开新窗口之前你正在发出,所以在尝试订阅时next
之前已经执行了因此订阅没有被解雇。您可以使用始终订阅的BehaviorSubject
,而不是Subject
:
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
private hub = new BehaviorSubject<Hub>(null);
请参阅:Angular 2 - Behavior Subject vs Observable?
摘录:
- 行为主题需要一个初始值,因为它必须始终返回订阅值,即使它没有收到
next()
和
- 常规observable仅在收到onnext
时触发
答案 1 :(得分:0)
您在订阅谷物后订阅。这对一个主题不起作用。
将private hub = new Subject<Hub>();
更改为此private hub = new ReplaySubject<Hub>(1);
答案 2 :(得分:0)
我设法使用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));
}
}
新选项卡在打开时会从此类中请求一些数据,父选项卡已存储。不是一个完美的解决方案,但它可以完成这项工作。