简体   繁体   English

为什么我的 Angular 组件值没有更新?

[英]Why doesn't my Angular component value update?

component1.html:组件 1.html:

<div>
    {{nums}}
</div>

TS: TS:

nums: Array<number> = [0, 1, 2, 3]; 

ngOnInit(): void {
    this.numService.getNum().subscribe((res) => {
    this.num = res;
  });
}

component2.html:组件 2.html:

<div (click)="addNum()">
  Add
</div>

TS: TS:

addNum(): void {
  this.numService.addNum(6);
}

NumService:数字服务:

public getNum() {
    return of(this.nums);
  }
  public addNum(num) {
    this.nums.push(num);
  }

Why when i click on addNum, in component1 doesn't work subscribe and value doesn't change.为什么当我点击 addNum 时,在 component1 中订阅不起作用并且值没有改变。 How to do it properly on this example?如何在这个例子中正确地做到这一点?

you are facing two problems:你面临两个问题:

  1. Every time you call the service function numService.getNum() you are creating a new observable.每次调用服务 function numService.getNum()时,您都在创建一个新的可观察对象。
  2. The function of creates a special observable which only emits its value once. function创建of一个特殊的可观察对象,它只发出一次值。

Instead you should have your service maintain a single observable, preferably a ReplaySubject (so it retains the previous value for subscriptions)相反,您应该让您的服务维护一个单独的可观察对象,最好是一个ReplaySubject (这样它会保留以前的订阅值)

something like this should work, in your service:在您的服务中,这样的事情应该有效:

  nums$ = new ReplaySubject<int[]>([]);
  nums = []

  public addNum(num) {
    this.nums.push(num);
    this.nums$.next(this.nums)
  }

then from your component, you should not subscribe (to avoid the usual observable memory leak ), but expose the service's observable:然后从您的组件中,您不应该订阅(以避免通常的observable memory leak ),而是公开服务的 observable:

  numsAtComponent$ = this.numService.nums$

And finally from your template, you subscribe to the component variable and show its value like this:最后,从您的模板中订阅组件变量并显示其值,如下所示:

<div>
 {{ numsAtComponent$ | async }}
</div>

The issue is that when you call this.numService.getNum() in ngOnInit the subscribe method is only called once ngOnInit is executed.问题是,当您在 ngOnInit 中调用this.numService.getNum()时,仅在执行ngOnInit后才调用订阅方法。 That happens because NumService.getNum() returns an observable created with the of() operator.发生这种情况是因为NumService.getNum()返回一个使用of()运算符创建的可观察对象。 Such an observable emits only once and then completes.这样的可观察对象只发射一次然后完成。 So you get only initial value of NumService.nums .所以你只得到NumService.nums的初始值。

Solution would be to turn numService.nums into a BehaviorSubject and subscribe to it.解决方案是将numService.nums变成一个 BehaviorSubject 并订阅它。

class NumService {
  private numsSubject$: BehaviorSubject<number[]> = new Subject<number[]>([]);

  nums$: Observable<number[]> = this.numsSubject$.asObservable();

  addNum(num: number): void {
    const nums = this.numsSubject$.getValue();
    this.numsSubject$.next([...nums, num]);
  }
}


class Component1 {
  nums: Array<number> = [0, 1, 2, 3]; 

  ngOnInit(): void {
    this.numService.nums$.subscribe((res) => {
      this.num = res;
    });
  }

  addNum(): void {
    this.numService.addNum(6);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 状态更改但组件不更新 - 角度 - State changes but component doesn't update - ANGULAR 为什么当上下文值更新时我的上下文没有更新? - why my context doesn't update when the context value updates? Angular:为什么我不能使用组件的方法作为可观察的回调来更新组件的属性? - Angular: why can't I use a method of my component as an obserable callback to update properties in the component? 为什么不在功能组件中状态更新 - Why doesn't state update in functional component Angular 路由器不显示我的组件 - Angular Router Doesn't Display My Component $ onChanges不会在组件初始化时更新值 - $onChanges doesn't update value on initialization of component 为什么在使用扩展运算符保存表单时父组件不更新,但在使用“推送”时它有效..Angular - Why parent component doesn't update when save form with spread operator ,but when use "push" it works ..Angular 我的 Angular 7 Web 组件 @Input<boolean> 当我绑定错误值时不起作用 - My angular 7 web component @Input<boolean> doesn't work when I bind a false value Angular 组件没有从可观察的服务获取器中分配值,为什么? - Angular component doesn't assign value from observable service getter, why? 为什么我的图像不更新? - Why doesn't my image update?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM