【问题标题】:How to make class Observable?如何使类可观察?
【发布时间】:2020-08-30 18:14:38
【问题描述】:

我有一个具有属性的类:

export class Model {
   public id: number;
   public name: string;
}

如何让这个类可观察,监听属性的变化。

我需要这样的东西:

let m = new Model();
m.id = 10;

聆听变化:

m.pipe(map() => m.id);

【问题讨论】:

    标签: angular typescript angular8 angular-observable


    【解决方案1】:
    let m = new Model();
    m.id = 10;
    
    
    const model$ = of(m);
    model$.pipe(map()=> m.id);
    

    【讨论】:

      【解决方案2】:

      您可以为您的类属性添加 getter 和 setter,在内部添加发射器,然后在类外部添加侦听器,该侦听器将侦听已触发的发射器

      【讨论】:

      • 你能分享一个样本吗?我需要在更改后获取模型并使用 httpRequest 进行 switchMap
      • 设置 id(id) { this.id = id; EventEmiter.emit('idchanged', id); }
      • 类似的,你可以从 EventEmiter 扩展你的类,并使用 this.emit
      • 如果您使用任何框架,它也可能具有内置发射器功能
      • 我用 Angular 怎么做?
      【解决方案3】:

      这是一个简单的例子。

      https://stackblitz.com/edit/angular-ivy-kc9e4q

      import { Component, OnInit, VERSION } from '@angular/core';
      import {BehaviorSubject} from 'rxjs';
      
      
      @Component({
        selector: 'my-app',
        templateUrl: './app.component.html',
        styleUrls: [ './app.component.css' ]
      })
      export class AppComponent implements OnInit {
      model: Model;
      
        ngOnInit() {
          this.model.id$.subscribe(newid => {
            // do something.
          });
        }
      }
      export class Model {
        // @ts-ignore
        private readonly _id = new BehaviorSubject<number>();
        readonly id$ = this._id.asObservable();
        // @ts-ignore
        private readonly _name = new BehaviorSubject<string>();
        readonly name$ = this._name.asObservable();
      
        get id(): number {
          return this._id.getValue();
        }
      
        set id(val) {
          this._id.next(val);
        }
      
        get name(): number {
          return this._name.getValue();
        }
      
        set name(val) {
          this._name.next(val);
        }
      }
      

      【讨论】:

        【解决方案4】:

        我的方法是将功能注入到构造函数中。我会避免在课堂上声明主题,因为它们很难自动整理。

        您可以注入主题,但更简单的替代方法是注入回调。

        在下面的测试类中,我允许注入每个属性的回调。如果值已更改,则在属性设置器中调用相关回调。

        export class MyClass {
          private _id: number;  
          private _name: string;
        
          constructor(private callback?: {
            id?: () => void,
            name?: () => void
          }) {}
        
          get id(): number { 
            return this._id;
          }
        
          set id(value: number) {
            if (value === this._id) {
              return;
            }
        
            this._id = value;
        
            if (this.callback && this.callback.id) {
              this.callback.id();
            }
          }
        
          get name(): string {
            return this._name;
          }
        
          set name(value: string) {
            if (value === this._name) {
              return;
            }
        
            this._name = value;
        
            if (this.callback && this.callback.name) {
              this.callback.name();
            }
          }
        }
        

        然后从其他地方使用它就相当简单了。

        myClass: MyClass = new MyClass({
          id: () => this.onIdChange()
        });
        
        ngOnInit() {
          this.myClass.id = 10;   
          this.myClass.name = 'Default' 
        }
        
        private onIdChange() {
          console.log(`id changed to ${this.myClass.id}`);
        }
        

        如果您真的需要,可以很简单地更改它以使用主题。然后调用代码将负责在适当的时候整理主题。

        演示:https://stackblitz.com/edit/angular-ivy-hgxkc3

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-10
          • 2018-08-29
          • 1970-01-01
          • 2015-03-13
          • 1970-01-01
          • 2014-07-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多