每当可观察对象改变其值时,观察者似乎都不会执行
The Observer seems not to be executed whenever the observable is changing its value
观察者似乎可以很好地初始化订阅。但是,当层的值发生变化时,观察者不会执行它应该执行的功能。我错过了什么吗?
您可以在 github 上查看我的存储库:
https://github.com/stefiHB/ol-angular-ionic
层-msg.service.ts
import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable, Subject} from 'rxjs';
import {customMapLayers} from './customMapLayers';
@Injectable({
providedIn: 'root'
})
export class LayerMsgService {
private layer = new BehaviorSubject<customMapLayers>(customMapLayers.pwd);
constructor() { }
getLayer() {
return this.layer.asObservable();
}
setLayer(mapLayer: customMapLayers) {
this.layer.next(mapLayer);
console.log('Setting new value...', this.layer.value);
}
}
MyButtons.ts
import {LayerMsgService} from './layer-msg.service';
import {customMapLayers} from './customMapLayers';
export class MyButton {
private layerService: LayerMsgService;
buttonPWD: HTMLButtonElement;
buttonOSM: HTMLButtonElement;
myElement: Element;
constructor(el: Element) {
this.layerService = new LayerMsgService();
this.buttonPWD = document.createElement('button');
this.buttonPWD.innerHTML = 'pwd';
this.buttonOSM = document.createElement('button');
this.buttonOSM.innerHTML = 'osm';
this.buttonOSM.addEventListener('click', () => this.changeLayer(customMapLayers.osm));
this.buttonPWD.addEventListener('click', () => this.changeLayer(customMapLayers.pwd));
el.appendChild(this.buttonPWD);
el.appendChild(this.buttonOSM);
}
changeLayer(l: customMapLayers) {
console.log('Request for Changing layer...');
this.layerService.setLayer(l);
}
}
app.component.ts
import {Component, OnDestroy, OnInit, Renderer2} from '@angular/core';
import {LayerMsgService} from './layer-msg.service';
import {Subscription} from 'rxjs';
import {MyButton} from './MyButton';
import {customMapLayers} from './customMapLayers';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
title = 'ObservablesMashup';
layer: customMapLayers;
layerSub: Subscription;
private myBtn: MyButton;
myText: Element;
constructor(private layerService: LayerMsgService) {
this.layerSub = this.layerService.getLayer().subscribe(
l => {
if (l) {
console.log('Getting layer... ', l);
this.layer = l;
}
});
}
ngOnInit(): void {
const el = document.getElementById('map');
console.log(el);
this.myBtn = new MyButton(el);
this.myText = document.getElementById('p1');
}
ngOnDestroy(): void {
this.layerSub.unsubscribe();
}
}
我尝试使用 btn.onclick = (event) => {...}
,但似乎无法解决问题。
我希望控制台记录:
Request for Changing layer...
Setting new value... PWD
Changing Layer... PWD
但是观察者的功能没有被执行,所以这是我点击按钮时的实际日志:
Request for Changing layer...
Setting new value... PWD
服务中的函数 setLayer
负责发出新值。
它在 controller.changeLayer
函数中调用,该函数本身在按钮点击时调用,定义稍早。
如果流没有产生新事件,则可能意味着按钮没有发挥作用。
看你用的是addEventListener
,我先叫你换成btn.onclick = (event) => {...}
试试看。
如果仍然无效,请尝试查看按钮点击是否有效,如果无效,则说明您没有点击正确的按钮,或者您超出了 Angular的上下文(参见 NgZone)
解决方法很简单。由于文档,我一开始就被误导了。根据这个url:
https://angular.io/tutorial/toh-pt4#provide-the-heroservice
"When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects into any class that asks for it. "
我认为 LayerMsgService 在所有 classes 之间共享。但是,我不得不在 MyButtons class.
中将其作为参数给出
层-msg.service.ts
constructor(el: Element, layerMsgService : LayerMsgService ) {
// code...
}
观察者似乎可以很好地初始化订阅。但是,当层的值发生变化时,观察者不会执行它应该执行的功能。我错过了什么吗?
您可以在 github 上查看我的存储库: https://github.com/stefiHB/ol-angular-ionic
层-msg.service.ts
import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable, Subject} from 'rxjs';
import {customMapLayers} from './customMapLayers';
@Injectable({
providedIn: 'root'
})
export class LayerMsgService {
private layer = new BehaviorSubject<customMapLayers>(customMapLayers.pwd);
constructor() { }
getLayer() {
return this.layer.asObservable();
}
setLayer(mapLayer: customMapLayers) {
this.layer.next(mapLayer);
console.log('Setting new value...', this.layer.value);
}
}
MyButtons.ts
import {LayerMsgService} from './layer-msg.service';
import {customMapLayers} from './customMapLayers';
export class MyButton {
private layerService: LayerMsgService;
buttonPWD: HTMLButtonElement;
buttonOSM: HTMLButtonElement;
myElement: Element;
constructor(el: Element) {
this.layerService = new LayerMsgService();
this.buttonPWD = document.createElement('button');
this.buttonPWD.innerHTML = 'pwd';
this.buttonOSM = document.createElement('button');
this.buttonOSM.innerHTML = 'osm';
this.buttonOSM.addEventListener('click', () => this.changeLayer(customMapLayers.osm));
this.buttonPWD.addEventListener('click', () => this.changeLayer(customMapLayers.pwd));
el.appendChild(this.buttonPWD);
el.appendChild(this.buttonOSM);
}
changeLayer(l: customMapLayers) {
console.log('Request for Changing layer...');
this.layerService.setLayer(l);
}
}
app.component.ts
import {Component, OnDestroy, OnInit, Renderer2} from '@angular/core';
import {LayerMsgService} from './layer-msg.service';
import {Subscription} from 'rxjs';
import {MyButton} from './MyButton';
import {customMapLayers} from './customMapLayers';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
title = 'ObservablesMashup';
layer: customMapLayers;
layerSub: Subscription;
private myBtn: MyButton;
myText: Element;
constructor(private layerService: LayerMsgService) {
this.layerSub = this.layerService.getLayer().subscribe(
l => {
if (l) {
console.log('Getting layer... ', l);
this.layer = l;
}
});
}
ngOnInit(): void {
const el = document.getElementById('map');
console.log(el);
this.myBtn = new MyButton(el);
this.myText = document.getElementById('p1');
}
ngOnDestroy(): void {
this.layerSub.unsubscribe();
}
}
我尝试使用 btn.onclick = (event) => {...}
,但似乎无法解决问题。
我希望控制台记录:
Request for Changing layer...
Setting new value... PWD
Changing Layer... PWD
但是观察者的功能没有被执行,所以这是我点击按钮时的实际日志:
Request for Changing layer...
Setting new value... PWD
服务中的函数 setLayer
负责发出新值。
它在 controller.changeLayer
函数中调用,该函数本身在按钮点击时调用,定义稍早。
如果流没有产生新事件,则可能意味着按钮没有发挥作用。
看你用的是addEventListener
,我先叫你换成btn.onclick = (event) => {...}
试试看。
如果仍然无效,请尝试查看按钮点击是否有效,如果无效,则说明您没有点击正确的按钮,或者您超出了 Angular的上下文(参见 NgZone)
解决方法很简单。由于文档,我一开始就被误导了。根据这个url:
https://angular.io/tutorial/toh-pt4#provide-the-heroservice
"When you provide the service at the root level, Angular creates a single, shared instance of HeroService and injects into any class that asks for it. "
我认为 LayerMsgService 在所有 classes 之间共享。但是,我不得不在 MyButtons class.
中将其作为参数给出层-msg.service.ts
constructor(el: Element, layerMsgService : LayerMsgService ) {
// code...
}