Angular startWith正在返回旧值

Angular startWith正在返回旧值,angular,rxjs,Angular,Rxjs,我为此挣扎了很长时间。我简化了我公司的应用程序: 闪电战 app.component.ts app.component.html 我将配置存储在一个对象中。在本例中,它是state对象。我在那里存储了一个简单的字符串值。我可以通过单击changeDate按钮来更改此值。然后它将更改对象的值,并通过Subject发送此新值,以便更新视图。但是,如果在发生更改后显示元素,则值保持不变 复制步骤: 点击changeDate按钮 显示的值是正确的 点击显示按钮 新显示的值是旧值,即使状态已更新 您可以使

我为此挣扎了很长时间。我简化了我公司的应用程序:

闪电战

app.component.ts

app.component.html

我将配置存储在一个对象中。在本例中,它是state对象。我在那里存储了一个简单的字符串值。我可以通过单击changeDate按钮来更改此值。然后它将更改对象的值,并通过Subject发送此新值,以便更新视图。但是,如果在发生更改后显示元素,则值保持不变

复制步骤:

点击changeDate按钮 显示的值是正确的 点击显示按钮 新显示的值是旧值,即使状态已更新 您可以使用BehaviorSubject而不是Subject,并且不需要startWith。这样,您将拥有最后发出的值,并且它将始终是实际值

链接到更新的stackblitz:

如中所述,不建议为同一个可观察对象创建多个异步管道。 这是因为每次使用异步管道时,都会创建一个新的订阅

在下面的片段中

我可以隐藏这个:{date$|async}

当visible=true时,将创建新订阅。 因为你的代码里有这个

this.date$=this.dateChanged$.pipe 从this.state.date开始, tapv=>console.log'emissed state value',v,//前面的值 它将发出this.state.date的上一个值

您还可以看到,每次再次显示日期时,都会创建一个新订阅

这里有一个解决方案,它将确保在给定的可观察对象上只使用一次异步管道

我可以隐藏这个:{{date}

这始终可见:{date}

使用这种方法,只创建一个订阅


另外,请确保检查控制台,以便更好地了解正在发生的事情。这就是我实际解决问题的方法

我知道BehaviorSubject可以工作,但我无法更改实现。我只是想理解为什么这个值没有更新。因为每次你隐藏并重新添加NGI隐藏的代码时,如果你创建了一个新的订阅,它应该从你定义的某个值开始。如果你想用[hidden]=隐藏它!可见,它将以您想要的方式工作。
import { Component } from '@angular/core';
import { Subject } from 'rxjs';
import {map, startWith, takeUntil, tap} from "rxjs/operators";

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public visible = false;
  private dateChangedSubj = new Subject();
  public dateChanged$ = this.dateChangedSubj.asObservable();

  private state = {
    date: "11.02.2019"
  };

  public date$;

  constructor() {
    this.date$ = this.dateChanged$.pipe(
      startWith(this.state.date),
    )
  }

  show() {
    this.visible = true;
  }

  hide() {
    this.visible = false;
  }

  changeDate() {
    this.state.date = "12.02.2019";
    this.dateChangedSubj.next(this.state.date);
  }

}
<button (click)="show()">Show</button>
<button (click)="hide()">Hide</button>
<button (click)="changeDate()">Change date</button>

<div *ngIf="visible">
  <p>This one I can hide: {{ date$ | async }}</p>
</div>

<p>This is always visible: {{date$ | async}}</p>