【问题标题】:Angular 2.x watching for variable changeAngular 2.x 观察变量变化
【发布时间】:2015-12-23 10:54:25
【问题描述】:

我正在从 angular 1.x 迁移到 2.x,但我的大脑仍然在 angular 1.x 中思考,很抱歉提出愚蠢的问题。

当我的 范围变量 组件属性之一发生变化时,我需要采取一些措施。我找到了解决方案,但我认为应该有更好的解决方案

export class MyApp {
    router: Router;
    location: Location;
    fixed: boolean = true;

    private set isFixed(value:boolean) {
        this.fixed = value;

        //TODO: look here
        console.log('isFixed changed', value);
    }

    private get isFixed():boolean {
        return this.fixed;
    }

    constructor(router: Router, location: Location) {
        this.router = router;
        this.location = location;
    }
}

查看console.log('isFixed changed', value); 行,这就是我需要的,它正在工作。但是我通过声明getter 和setter 做到了,但是没有更好的方法来观察变量吗?就像在角度 1.x 中是 $scope.$watch?

我认为我的组件代码应该是这样的

export class MyApp {
    router: Router;
    location: Location;
    isFixed: boolean = true;

    //TODO: $watch for isFixed change {
        console.log('isFixed changed', value);
    // }

    constructor(router: Router, location: Location) {
        this.router = router;
        this.location = location;
    }
}

【问题讨论】:

  • 您的代码中的isFixed 是如何更改的?什么在修改值?

标签: javascript angular


【解决方案1】:

您可能会发现 this answer to Delegation: EventEmitter or Observable in Angular2 很有帮助(为我工作)。

基本上你可以使用BehaviorSubject,它允许你为你感兴趣的属性设置一个初始值,然后订阅对该属性的更改,无论该服务被注入到哪里。

例如

export class SomeService {
  private fixed = new BehaviorSubject<boolean>(true); // true is your initial value
  fixed$ = this.fixed.asObservable();

  private set isFixed(value: boolean) {
    this.fixed.next(value);
    console.log('isFixed changed', value);
  }

  private get isFixed():boolean {
    return this.fixed.getValue()
  }

  constructor(router: Router, location: Location) {
    this.router = router;
    this.location = location;
  }
}

然后在对fixed 值感兴趣的类(例如组件)中:

export class ObservingComponent {
  isFixed: boolean;
  subscription: Subscription;

  constructor(private someService: SomeService) {}

  ngOnInit() {
    this.subscription = this.someService.fixed$
      .subscribe(fixed => this.isFixed = fixed)
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

更新值:

export class Navigation {
  constructor(private someService: SomeService) {}

  selectedNavItem(item: number) {
    this.someService.isFixed(true);
  }
}

【讨论】:

    【解决方案2】:

    您可能想要实现OnChanges 接口并实现ngOnChanges() 方法。 每当组件输入或输出绑定值之一发生更改时,都会调用此方法。 另见https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

    飞镖代码示例

      @Input() bool fixed;
    
      @override
      void ngOnChanges(Map<String, SimpleChange> changes) {
        print(changes);
      }
    

    【讨论】:

    • @GünterZöchbauer 对于 regular 属性有任何类似的解决方案吗?
    • @tchelidze 将属性设为 getter/setter 并从 setter 调用您的代码。
    • @GünterZöchbauer 谢谢。但是,似乎不自然,财产本身不应该关心其他人想如何对其变化作出反应。我从 Ember 搬到了那里,创建 observers 非常简单。
    • Angular 不为此用例提供任何特殊支持。
    【解决方案3】:

    见Angular2 Component Interaction(有代码示例)。

    对您的问题的简短回答是,这实际上取决于您要做什么。即使那样,也有多种方法可以做你想做的事情,即使它不是真的打算做的。所以,我认为最好花几分钟时间看看他们关于组件交互和表单的文档。

    我个人的偏好是在属性发生变化时使用事件。 ngOnChanges 事件可用于此,但我更喜欢使用 @Input 和 @Output 和 form value changed events (Angular2 Forms)。

    希望这对您有所帮助并为您指明方向。

    【讨论】:

      【解决方案4】:

      通过此服务自动获取更新值

      注意:我在 Angular 9 中对其进行了测试 我的服务文件

      import { Injectable } from '@angular/core';
      import { BehaviorSubject } from 'rxjs';
      
      @Injectable({
          providedIn: 'root'
      })
      export class SharedService {
          private fixed= new BehaviorSubject<boolean>(false);
          fixed$ = this.fixed.asObservable();
      
          constructor() {}
      
          updateFixedValue(value: boolean) {
              this.fixed.next(value);
              console.log('fixed changed', value);
          }
      }
      

      现在您可以在任何组件(在 ngOnInit 或您想要的任何地方)中获取价值,如下所示 注意:此值将在更新后自动更改

      this.sharedService.fixed$.subscribe(val=>{ this.isFixed = val; });
      

      您可以从任何组件更新或设置新值,如下所示

      this.sharedService.updateFixedValue(your_boolean_value);
      

      谢谢,希望对你有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多