【问题标题】: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);
});

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

【问题讨论】:

    标签: javascript angular typescript angular-components


    【解决方案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{}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-14
        • 1970-01-01
        相关资源
        最近更新 更多