【问题标题】:Angular BehaviorSubject Unexpected Behavior: Changing without Next()Angular BehaviorSubject 意外行为:在没有 Next() 的情况下进行更改
【发布时间】:2018-06-20 04:33:25
【问题描述】:

我在 Angular 中的 BehaviorSubject 出现了一些意想不到的“行为”。当我的应用加载时,我会得到一堆对象(状态)并将它们设置为可观察对象:

public statuses$ = new BehaviorSubject<any>(null)

public getStatuses(): Promise<any> {
    return this.http.get<any>(this.url, { headers: this.headers })
        .toPromise()
        .then(res => {
            this.statuses$.next(res);
            return res;
        });
}

在我的组件中,我在 ngOnInit 期间订阅并将它分配给一个变量,以便我可以在我的模板中使用它:

ngOnInit() {
    this.appointmentStatusesService.statuses$.subscribe(statuses => {
        this.statuses = statuses; 
    });        
}

足够简单。我正在做的事情的简短版本:我在带有 ngFor 的 HTML 模板中循环浏览这些状态。用户点击状态,它通过表单显示状态。 (这是用户点击状态时使用的函数):

public viewStatus(seqNo: number) {
    const statuses = this.appointmentStatusesService.statuses$.getValue();
    for (let x = 0; x < statuses.length; x++) {
        if (statuses[x].seqno === seqNo) {
            this.currentStatus = statuses[x];
            break;
        }
    }
}

现在,我遇到的问题是对表单所做的任何更改也会更改 statuses$ 可观察的,即使我没有调用 .next()。这是我的表单的样子:

<input type="text" class="form-control" [(ngModel)]="currentStatus.name">

不知何故,当 currentStatus 的名称被改变时(当用户点击“VIEW STATUS”时,它也改变了 statuses$ observable。换句话说,对 currentStatus 对象所做的任何更改也会对状态进行$ observable。好像有某种双向绑定。我的印象是,为了将更改推送到 BehaviorSubject,您必须调用 .next() 方法。我可能误解了 BehaviorSubject 的工作原理,但是如果有人能告诉我哪里出错了,我将不胜感激:\谢谢!

【问题讨论】:

    标签: angular rxjs behaviorsubject


    【解决方案1】:

    我认为问题出在这里:

    this.currentStatus = statuses[x];
    

    因此,您只是在复制状态的引用,因此如果您编辑 currentStatus,您也在编辑列表中的状态。您可以尝试的第一件事是创建一个这样的新对象

    this.currentStatus = { ...statuses[x] };
    

    我的一般建议是稍微重写它以避免订阅和过多的本地状态。我已经用虚拟数据完成了它,它工作正常并且非常简单:

    // 模板

    <p *ngFor="let s of statusses$ | async" (click)="statusClicked(s)">{{ s }}</p>
    <input type="text" class="form-control" [(ngModel)]="currentStatus">
    

    // 脚本

    statusses$ = new BehaviorSubject(['status1', 'status2', 'status3']);
    currentStatus: string;
    statusClicked = (s: string) => this.currentStatus = s;
    

    【讨论】:

      猜你喜欢
      • 2014-07-13
      • 2016-06-03
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多