【问题标题】:Component cannot subscribe to data source组件无法订阅数据源
【发布时间】:2018-01-08 01:43:23
【问题描述】:

我让这个组件监听来自服务的消息。 请注意,下面显示的每个 console.log() 语句至少被命中一次,所有内容都会被记录。 也就是说,除了“将消息添加到数组”之外 - 不会被记录,但应该被记录!

这是组件:

import {Component, OnInit, Inject} from '@angular/core';
import {ChromeDataService} from '../../../../shared/services/events';


@Component({
  providers: [ChromeDataService],
  selector: 'app-events-list',
  templateUrl: './events-list.component.html',
  styleUrls: ['./events-list.component.scss']
})

export class EventsListComponent implements OnInit {

  isShowEventsList = false;
  events = [];

  constructor(private data: ChromeDataService) {
       console.log('events list component is constructed.');
  }

  ngOnInit() {
    console.log('events list component ngOnInit called.');
    this.data.currentMessage.subscribe(message => {
      console.log('adding message to array: ', message);
      this.events.push(message);
    })
  }

  showEventsList() {
    this.isShowEventsList = true;
  }

  hideEventsList() {
    this.isShowEventsList = false;
  }

}

这里是数据源(一个 Angular 服务):

///<reference types="chrome"/>

import {Injectable, Component, Inject} from '@angular/core';
import {ReplaySubject} from "rxjs/ReplaySubject";

@Injectable()
export class ChromeDataService {

  private messageSource = new ReplaySubject<Object>();
  public currentMessage = this.messageSource.asObservable();
  private isListening: boolean = false;
  private listener: any;

  constructor() {

    const self = this;
    this.listener = function (msg, sender, sendResponse) {
      const parsed = JSON.parse(msg);
      console.log('extension received a message:', parsed);
      self.changeMessage(parsed);
    };
  }

  changeMessage(message: Object) {
    this.messageSource.next(message);
  }

  stopListening() {
    this.isListening = false;
    chrome.runtime.onMessage.removeListener(this.listener);
  }

  startListening() {
    this.isListening = true;
    chrome.runtime.onMessage.addListener(this.listener);
  }


}

有谁知道为什么当changeMessage() 被调用时,subscribe() 回调没有被调用?

一个重要提示是,当我使用 new BehaviorSubject&lt;Object&gt;('initial'); 而不是 new Subject&lt;Object&gt;() 时,initial 确实到达并记录了“向数组添加消息”。

【问题讨论】:

  • 请注意,startListening() 最初是被调用的,这就是我们“扩展收到消息”确实被记录的原因
  • 我试过 Rx.Subject 和 Rx.ReplaySubject 都因为某种原因都不起作用,不知道为什么
  • 服务似乎被创建了不止一次!所以当组件订阅时,它订阅了旧版本的服务,然后创建了一个新的服务,并且组件订阅了一个旧的..很奇怪,不知道如何修复。
  • 我通过问一个不同的问题找到了答案 - stackoverflow.com/questions/48143639/…

标签: angular google-chrome-extension rxjs rxjs5 angular5


【解决方案1】:

当应用通过chrome.runtime.sendMessagechrome.runtime.onMessage 从后台页面获取响应时,我使用 NgZone 修补了 Chrome 消息传递 API 以更新视图。
这是我在 chrome 扩展中使用的服务。

import { Injectable, NgZone } from "@angular/core";
import { Subject } from "rxjs/Subject";
import { Observable } from "rxjs/Observable";

/*
NgZone monkey patched chrome messaging service.
*/
@Injectable()
export class ChromeMsgSrv {

   constructor(private _ngZone: NgZone) { }

   public send(msg: any, cb: (resp: any) => any) {
      chrome.runtime.sendMessage(msg, (resp: any) => {
         this._ngZone.run(() => cb(resp))
      })
   }

   public onMsg(cb: (msg: any) => any) {
      chrome.runtime.onMessage.addListener((msg: any) => {
         this._ngZone.run(() => cb(msg))
      })
   }

}

@Olegzandr,我从DevKit.life 来到这个线程。我想与您联系以解决此问题,但在您的网站上找不到任何联系我们的页面(假设 Devkit.life 是您的)。此外,这篇文章的反向链接是纯文本,而不是锚或可点击元素。希望您能更正您网站上存在的这些问题。

【讨论】:

    【解决方案2】:

    简而言之,因为我在不止一个地方调用providers:[ChromeDataService],所以我的服务被创建了不止一次。所以我订阅了错误的服务。

    见:

    @Injectable service does not seem to be a singleton

    【讨论】:

      【解决方案3】:

      试试这个:

      changeMessage = (message : Object) => {}
      

      并使用Subject 而不是replay

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-23
        • 2020-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多