与在另一个 window 中打开的组件交互

Interact with a component opened in another window

在我的项目中,我需要在 2 个不同的屏幕中显示 2 个不同的组件。所以我打开两个浏览器 windows 并显示这些组件。 我想知道是否可以从第一个 window 中的组件与第二个中的另一个组件进行交互?

我尝试在服务中创建 Subject。但是每当我尝试在另一个 window 的组件中订阅这个主题时,它就不起作用。这是我的工作:

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);
});

但是不起作用。我不确定如何实现我需要的。

订阅一个 Subject 是行不通的,因为它只存在于那个单一 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

});

David 提供的以上答案将有效。 特别是因为 Angular 2 不仅设计用于 运行 在您的浏览器中,而且还适用于移动设备、服务器或网络工作者,在这些地方 window 等对象可能不可用。

因此,建议的方法是将此类对象包装起来,并通过依赖注入机制注入它们。这样就可以根据 Angular 应用程序 运行ning 的环境更改给定对象的具体 运行 时间实例。我们想要达到的结果如下:

import { WindowRef } from './WindowRef';
@Component({...})
class MyComponent {
    constructor(private winRef: WindowRef) {
        // getting the native window obj
        console.log('Native window obj', winRef.nativeWindow);
     }
}

包装 window 的一种非常简单易行的方法是创建 Angular 2 服务。这就像创建一个 ES6 class 并用 @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{}