Angular 6:当她更改我的服务时更新我组件中的值

Sci*_*aud 7 service components typescript angular

我的目标原则上很简单,但我无法实现:我希望在更改服务变量时更新我的​​一个组件。

为了更好地解释我的问题,这里有一个例子:

在这里,我有一项增加或减少一些积分的服务。当它收到对其功能之一的调用时,它会减少或增加此点数。它还说明这个变量是偶数还是奇数

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

@Injectable({
  providedIn: 'root'
})
export class TestService {
  Number: number = 0;
  IsOdd: boolean = false;

  constructor() {}

  IncreaseNumber() {
    this.Number = this.Number + 1;
    this.IsOdd = !this.IsOdd;
  }

  DecreaseNumber() {
    this.Number = this.Number - 1;
    this.IsOdd = !this.IsOdd;
  }
}
Run Code Online (Sandbox Code Playgroud)

*这里,我有我的组件,它需要知道我的数字是偶数还是奇数。

初始化时,没问题!它知道!

如何,每次我的服务 (test.service.ts) 中的数字发生变化时,我都会确保我的组件 (test.component.ts) 中的值对/导入发生变化?*

import { Component, OnInit } from '@angular/core';
import { TestService } from '../test.service'

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit {

  IsOdd: boolean = false;

  constructor(MyService: TestService) {}

  ngOnInit() {
    this.IsOdd = MyService.IsOdd;
  }

}
Run Code Online (Sandbox Code Playgroud)

我该怎么做?

我的组件是否需要以subscribe某种方式提供给我的服务?或者我是否必须使用一种功能ngOnInit来更新?

提前致谢

Sid*_*era 6

如果这些服务变量是对象或数组等复杂类型,它会自动更新,因为这些是引用类型。但是由于您有类型为 number 和 boolean 的 Service 变量,因此它们不会自动更新,因为它们是原始类型,因此是按值传递的。

所以你必须使用BehaviorSubjects 并公开它们asObservables。您将BehaviorSubject通过调用next它们的方法来更新这些s的值。就是这样:

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

@Injectable({
  providedIn: 'root'
})
export class TestService {
  private myNumberValue = 0;
  private isOddValue = false;
  private myNumber: BehaviorSubject<number> = new BehaviorSubject<number>(this.myNumberValue);
  private isOdd: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  myNumber$: Observable<number> = this.myNumber.asObservable();
  isOdd$:  Observable<boolean> = this.isOdd.asObservable();

  constructor() {}

  increaseNumber() {
    this.myNumberValue = this.myNumberValue + 1;
    this.myNumber.next(this.myNumberValue);
    this.isOddValue = !this.isOddValue;
    this.isOdd.next(this.isOddValue);
  }

  decreaseNumber() {
    this.myNumberValue = this.myNumberValue - 1;
    this.myNumber.next(this.myNumberValue);
    this.isOddValue = !this.isOddValue;
    this.isOdd.next(this.isOddValue);
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您的组件,所有你需要做的是subscribepublicLY暴露Observable从服务价值:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { TestService } from '../test.service'
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss']
})

export class TestComponent implements OnInit, OnDestroy {

  isOdd: boolean;
  subscription: Subscription;

  constructor(private testService: TestService) {}

  ngOnInit() {
    this.subscription = this.testService.isOdd$.subscribe(isOdd => this.isOdd = isOdd);
  }

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

}
Run Code Online (Sandbox Code Playgroud)

现在,由于您已经在组件初始化期间调用subscribeisOdd$in ngOnInitwhich,isOdd因此每次isOddValue服务中发生更改时,您的 Component 都会更新。

此外,由于这是自定义的,subscription因此应该将其分配给 Component( subscription) 中的属性,该属性的类型Subscription是我们从subscribe方法中作为返回值获得的类型。我们将不得不调用unsubscribengOnDestroy以避免内存泄漏。

PS:根据Angular 的 Styleguide,Angular 类中的属性和方法名称应采用小驼峰式

一定要使用小驼峰命名属性和方法。