【问题标题】:Watch variable changes in angular观察角度的变量变化
【发布时间】:2018-09-29 23:11:22
【问题描述】:

我正在尝试从角度服务订阅变量的更改,而不是在组件中订阅它。这是我测试的代码:

服务:

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

@Injectable()

export class testService {
  detectChanges = new Subject();
  myObject : any = {
    test:"Test"
  };
  constructor() {
    this.detectChanges.subscribe((data) => {
      console.log("changed");
    });
  }
}

组件:

import { Component } from '@angular/core';
import { testService } from './test-service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  $s;
  constructor(private test: testService) {
    this.$s = this.test.myObject;
  }
}

html:

<input [(ngModel)]="$s.test">
<h1>{{$s.test}}</h1>

有没有办法做到这一点?就像在 angularjs $watch 这是一个例子https://stackblitz.com/edit/angular-cmyy66?file=src%2Fapp%2Fapp.component.html 在示例中,myObject 将使用输入进行更改

【问题讨论】:

  • 您正在寻找BehaviorSubject(接收推送更新),而不是计划Subject
  • @Z.Bagley 我试过了,但它只在第一次加载页面时有效。

标签: angular


【解决方案1】:

我在stackblitz上创建了一个示例

基本上你的服务是这样的:

@Injectable()
export class TestService{
  private detectChanges: Subject<any> = new Subject<any>();
  myobject$ = this.detectChanges.asObservable();

 constructor() {
   this.detectChanges.subscribe((data) => {
     console.log("changed", data);
   });
 }

 changeObject(myobject: any) {
   this.detectChanges.next(myobject);
 } 
}

订阅和更改您的主题

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

  constructor(private testService: TestService) {
    this.testService.myobject$.subscribe((data) => {
      this.name = data;
    });
  }

  change(input) {
    this.testService.changeObject(input);
  }
}

希望对您有所帮助。

【讨论】:

  • 这行得通,但这不是我需要的。我不想使用组件中的任何功能。请参阅链接中的示例。
  • @FerhadOthman,再看看我的 stackblitz,你需要混合使用 getter/setter 才能使其工作。
【解决方案2】:

您可以为此使用 setter:

服务:

 private _myObject;
 public get myObject() { return this._myObject; };
 public set myObject(val) { 
     console.log("The value is changing");
     this._myObject = val
 };

在组件中:

 constructor(public test: testService) {
    this.test.myObject="New test"; // This would cause "The value is changing" to be logged
 }

如果您愿意,也可以在 set 函数中通知您的主题

Here is a StackBlitz demo

【讨论】:

  • 这仅在第一次加载页面时有效。我想在每次 myObject 更改时检测更改。请查看更新。我添加了一个示例。
  • 在示例中 myObject 将使用输入进行更改
【解决方案3】:

BehaviorSubject 和 getter/setter 的最简单解决方案;

@Injectable()
export class testService {
  myObject: any = {
    _test$: new BehaviorSubject("Test"),
    set test(val) {
      this._test$.next(val);
    },
    get test() {
      return this._test$.getValue();
    }
  };
  constructor() {
    this.myObject._test$.subscribe((data) => {
      console.log("changed", data);
    });
  }
}

也可以看看OnChanges

【讨论】:

    猜你喜欢
    • 2019-03-24
    • 2019-04-15
    • 2016-08-18
    • 2014-10-21
    • 2020-05-11
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    相关资源
    最近更新 更多