在我的项目中,我需要在2个不同的屏幕中显示2个不同的组件。因此,我打开了两个浏览器窗口并显示了这些组件。 我想知道是否可以从第一个窗口中的组件交互到第二个窗口中的另一个组件?
我尝试在服务中创建Subject
。但是每当我尝试在另一个窗口的组件中订阅此Subject时,它都将不起作用。这是我的工作:
export class MyService {
public navigationTrigger: Subject<NavigationParams> = new Subject();
constructor(private _http: Http) {
this.navigationTrigger.next(params);
}
}
在一个组件中,我订阅它:
this.watsonService.navigationTrigger.subscribe((navigation) => {
this.updateNavigation(navigation);
});
但是不起作用。我不确定如何实现自己的需求。
答案 0 :(得分:1)
订阅主题将不起作用,因为它仅位于该单个Window的范围内。
如果要使用它与两个不同的用户进行实时通信,则应该使用WebSockets。 如果是同一用户,则可以使用localStorage。
发件人
localStorage.setItem("someKey", "someValue");
接收器部分
window.addEventListener('storage', storageEventHandler, false);
function storageEventHandler(evt) {
alert("storage event called key: " + evt.key);
}
您也可以将其包装在Observable中,请参见此示例
Rx.Observable.create(observer => {
window.addEventListener('storage', storageEventHandler, false);
function storageEventHandler(evt) {
alert("storage event called key: " + evt.key);
observer.onNext(evt);
}
// todo: return unsubscribe function which will remove that eventListener
});
答案 1 :(得分:0)
以上由大卫提供的答案将起作用。 尤其是由于Angular 2不仅要在浏览器中运行,而且还要在移动设备上运行,因此服务器或Web工作者可能无法使用诸如Window之类的对象。
因此,建议的方法是包装此类对象并通过依赖项注入机制注入它们。这样,可以根据Angular应用程序运行的环境来更改给定对象的具体运行时实例。我们想要实现的结果如下:
import { WindowRef } from './WindowRef';
@Component({...})
class MyComponent {
constructor(private winRef: WindowRef) {
// getting the native window obj
console.log('Native window obj', winRef.nativeWindow);
}
}
包装窗口的一种非常简单明了的方法是创建Angular 2服务。就像创建ES6类并使用@Injectable装饰它一样简单。
import { Injectable } from '@angular/core';
function _window() : any {
// return the global native browser window object
return window;
}
@Injectable()
export class WindowRef {
get nativeWindow() : any {
return _window();
}
}
将WindowRef注册为提供者
@NgModule({
...
providers: [ WindowRef ]
})
export class AppModule{}