【问题标题】:The Observer seems not to be executed whenever the observable is changing its value每当可观察对象更改其值时,观察者似乎都不会被执行
【发布时间】:2019-10-10 15:47:08
【问题描述】:

观察者似乎很好地初始化了订阅。但是,当图层的值发生变化时,观察者不会执行它应该执行的功能。我错过了什么吗?

您可以在 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) =&gt; {...},但似乎无法解决问题。

我希望控制台能够记录:

Request for Changing layer...
Setting new value... PWD
Changing Layer... PWD

但是观察者的功能没有被执行所以这是我点击按钮时的实际日志:

Request for Changing layer...
Setting new value... PWD

【问题讨论】:

    标签: angular typescript angular7 openlayers-5 rxjs-observables


    【解决方案1】:

    服务中的函数setLayer 负责发出新值。

    它在controller.changeLayer 函数中被调用,它本身在按钮点击时被调用,定义稍早。

    如果流没有产生新的事件,这可能意味着按钮没有发挥作用。

    看到你用addEventListener,我先告诉你换成btn.onclick = (event) =&gt; {...}试试。

    如果它仍然不起作用,请尝试查看按钮点击是否有效,如果它们不起作用,则意味着您没有点击正确的按钮,或者您超出了 Angular 的上下文(请参阅NgZone )

    【讨论】:

    • btn.onclick = (event) =&gt; {...} 似乎无法解决问题。但无论哪种方式,我认为它们都可以工作的按钮(?)。 controller.changeLayer 正在执行。 map.service.ts 中的 setLayer() 也被执行,因为它在控制台中记录消息:“正在设置新值...”并打印正确的值。
    • @skassi 你能提供一个minimal reproducible example 你的问题吗?如果没有任何证据表明它不起作用,很难为您提供帮助……除此之外,我看不出有什么问题!
    • 我在这里发布问题之前尝试过,但我无法制作一个最小的可重现示例。不过我会再试一次。我还在那个特定项目中发布了我的 GitHub 存储库,所以如果你有时间,可以下载它。无论如何,我将再次尝试最小可重现示例。谢谢。
    • @skassi 我在公司计算机上,我受到防火墙的限制(我们使用 bitbucket ......是的)。对于minimal reproducible example,您可以模拟大部分代码,只要问题被重现。如果您无法做到,那么这可能意味着您在某处有错字/错误!因此,从您的 minimal reproducible example 开始,并重建您的组件/服务,以便它们工作。
    • 我试图提供一个更简单的可重现示例。 app.component.ts 中的观察者也有同样的问题
    【解决方案2】:

    解决方案很简单。由于文档,我在开始时被误导了。根据这个网址:

    https://angular.io/tutorial/toh-pt4#provide-the-heroservice

    “当你在根级别提供服务时,Angular 会创建一个单一的、共享的 HeroService 实例并注入到任何需要它的类中。”

    我认为 LayerMsgService 是在所有类之间共享的。但是,我必须在 MyButtons 类中将其作为参数提供。

    层-msg.service.ts

    constructor(el: Element, layerMsgService : LayerMsgService  ) {
    // code...
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 2018-05-26
      相关资源
      最近更新 更多