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

Posted

技术标签:

【中文标题】与在另一个窗口中打开的组件交互【英文标题】:Interact with a component opened in another window 【发布时间】:2018-11-30 13:41:41 【问题描述】:

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

我尝试在服务中创建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);
);

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

【问题讨论】:

【参考方案1】:

订阅主题将不起作用,因为它只存在于该单个窗口的范围内。

如果您想使用它与两个不同的用户进行实时通信,那么您应该使用 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

);

【讨论】:

【参考方案2】:

大卫提供的上述答案将起作用。 尤其是因为 Angular 2 不仅设计为在您的浏览器中运行,而且还设计为在移动设备、服务器或 Web Worker 上运行,因为窗口等对象可能不可用。

因此建议的方法是包装这些对象并通过依赖注入机制注入它们。通过这种方式,可以根据 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

【讨论】:

以上是关于与在另一个窗口中打开的组件交互的主要内容,如果未能解决你的问题,请参考以下文章

Office DCOM 组件交互权限设置

如何在另一个组件中使用来自组件的表单

React 如何订阅在另一个组件中声明的可观察对象

Android四大组件——Activity

Angular - 是否可以创建AppComponent的弹出窗口?

如何从我的组件打开的窗口中反应性地检查更改