组件无法订阅数据源
Component cannot subscribe to data source
我让这个组件侦听来自服务的消息。 请注意,下面显示的每个 console.log() 语句至少被命中一次,所有内容都会被记录下来。 也就是说,除了 "adding message to array" - 它不会被记录,但是它应该被记录下来!
组件如下:
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<Object>('initial');
而不是 new Subject<Object>()
- 然后 initial
确实到达并且 'adding message to array' 被记录。
试试这个:
changeMessage = (message : Object) => {}
并使用 Subject
而不是 replay
。
简而言之,因为我在不止一个地方调用 providers:[ChromeDataService]
,所以我的服务被创建了不止一次。所以我订阅了错误的服务。
参见:
@Injectable service does not seem to be a singleton
我用 NgZone 修补了 Chrome 消息传递 API,以便在应用通过 chrome.runtime.sendMessage
或 chrome.runtime.onMessage
.[=18 从后台页面获取响应时更新视图=]
这是我在 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
来到这里的。我想与您联系以解决此问题,但在您的网站上找不到任何 contact-us 页面(假设 Devkit.life 是您的)。此外,此 post 的反向链接是纯文本,而不是锚点或可点击元素。希望您能纠正网站上出现的这些问题。
我让这个组件侦听来自服务的消息。 请注意,下面显示的每个 console.log() 语句至少被命中一次,所有内容都会被记录下来。 也就是说,除了 "adding message to array" - 它不会被记录,但是它应该被记录下来!
组件如下:
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<Object>('initial');
而不是 new Subject<Object>()
- 然后 initial
确实到达并且 'adding message to array' 被记录。
试试这个:
changeMessage = (message : Object) => {}
并使用 Subject
而不是 replay
。
简而言之,因为我在不止一个地方调用 providers:[ChromeDataService]
,所以我的服务被创建了不止一次。所以我订阅了错误的服务。
参见:
@Injectable service does not seem to be a singleton
我用 NgZone 修补了 Chrome 消息传递 API,以便在应用通过 chrome.runtime.sendMessage
或 chrome.runtime.onMessage
.[=18 从后台页面获取响应时更新视图=]
这是我在 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
来到这里的。我想与您联系以解决此问题,但在您的网站上找不到任何 contact-us 页面(假设 Devkit.life 是您的)。此外,此 post 的反向链接是纯文本,而不是锚点或可点击元素。希望您能纠正网站上出现的这些问题。