将数据发射到可观察的

发布于 2025-02-10 08:24:34 字数 1595 浏览 1 评论 0原文

上的示例代码。

这是

该服务看起来像这样:

import { Injectable } from '@angular/core';

import { Observable, Observer } from 'rxjs';

class DataEmitter {
  public eventCallback: () => void;

  constructor() {
    setInterval(() => {
      if (this.eventCallback) this.eventCallback();
    }, 1000);
  }
}

let emitter = new DataEmitter();

@Injectable({
  providedIn: 'root',
})
export class DataService {
  private counter = 1;

  public dataSource = new Observable<number>((observer: Observer<number>) => {
    emitter.eventCallback = () => {
      observer.next(this.counter++);
    };
  });

  constructor() {}
}

相应的组件订阅可观察到的数据并希望显示数据:

import { Component, VERSION, OnInit } from '@angular/core';

import { DataService } from './data.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular ' + VERSION.major;

  presentableData: number[] = [];

  trigger = 0;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.dataService.dataSource.subscribe((num) => {
      console.log('presentableData.length: ' + this.presentableData.length);
      this.presentableData.push(num);
    });

    setInterval(() => this.trigger++, 10000);
  }
}

这不起作用(也不丢弃错误),因为全局数据发射对象不在可观察的订阅范围内我认为方法。 但是,数据将到达组件并填充PresentableData数组(如日志输出中可以看到)。但是该组件不会再次渲染。 但是,如果您通过另一个绑定变量触发它,它将显示所有数据。

我希望每秒都会更新视图,而不仅仅是当“触发”递增时。

我的方法是完全错误的,这是正常/预期的行为,还是这是有角度的错误?

Here's the sample code on stackblitz

I have a data service that gets it's data asynchronously from a global object (in the real project it emits the data via EventEmitter).

The service looks something like this:

import { Injectable } from '@angular/core';

import { Observable, Observer } from 'rxjs';

class DataEmitter {
  public eventCallback: () => void;

  constructor() {
    setInterval(() => {
      if (this.eventCallback) this.eventCallback();
    }, 1000);
  }
}

let emitter = new DataEmitter();

@Injectable({
  providedIn: 'root',
})
export class DataService {
  private counter = 1;

  public dataSource = new Observable<number>((observer: Observer<number>) => {
    emitter.eventCallback = () => {
      observer.next(this.counter++);
    };
  });

  constructor() {}
}

The corresponding Component subscribes to the observable and wants to display the data:

import { Component, VERSION, OnInit } from '@angular/core';

import { DataService } from './data.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular ' + VERSION.major;

  presentableData: number[] = [];

  trigger = 0;

  constructor(private dataService: DataService) {}

  ngOnInit(): void {
    this.dataService.dataSource.subscribe((num) => {
      console.log('presentableData.length: ' + this.presentableData.length);
      this.presentableData.push(num);
    });

    setInterval(() => this.trigger++, 10000);
  }
}

This doesn't work (doesn't throw an error either) because the global data emitting object is not in the scope of the Observable subscribe method I think.
Nonetheless the data will get to the Component and populate the presentableData array (as can be seen in the log output). But the Component will not render again.
But if you trigger it via another bound variable, it will show all the data.

I would expect the view to be updated every second and not only when 'trigger' is incremented.

Is my approach completely wrong and this is normal/expected behaviour, or is this a bug with angular?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

命硬 2025-02-17 08:24:34

如果您的数据来自事件侦听器,那么您可以将其

scroll$ = fromEvent(window, 'scroll')

转换为可观察到的事件侦听器。

除此之外,您的数据发射器已经由RXJS以主题的形式涵盖

obs$ = new BehaviorSubject<number>(0); // Holds the last value and emits it on watch start
obs$ = new Subject<number>(); // don't hold a value, doesn't emit on watch start

If your data comes from an event listener, then you have this

scroll$ = fromEvent(window, 'scroll')

Which transforms an event listener into an observable.

Other than that, your data emitter is already covered by RxJS in the form of subjects

obs$ = new BehaviorSubject<number>(0); // Holds the last value and emits it on watch start
obs$ = new Subject<number>(); // don't hold a value, doesn't emit on watch start
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文