【问题标题】:NGRX/RXJS observer not emitting on page refreshNGRX/RXJS 观察者在页面刷新时未发出
【发布时间】:2020-09-21 19:01:18
【问题描述】:

我有一个允许用户编辑条目的组件。如果用户从前一个组件(表)到达编辑页面,我的观察者能够从 Store 中选择用户并使用正确的数据填充字段。

但是,如果我刷新页面,观察者确实会继续返回 null。奇怪的是,编辑表单上的 nGif 填写了用户的正确标签。这告诉我 Observable 对象不为空,因为 nGif 不会呈现标签。订阅它的观察者似乎是问题所在。

表格:

<form id="editContainer" [formGroup]="editForm" *ngIf="userObjectUnderEdit | async as userEdit">
        <div class="form-group">
            <mat-form-field appearance="standard">
            <mat-label>{{userEdit.name}}</mat-label>
            <input class="formInput" matInput placeholder="{{userEdit.name}}" formControlName="name" required>
            </mat-form-field>
        </div>
        <div class="form-group">
            <mat-form-field appearance="standard">
                <mat-label>{{userEdit.email}}</mat-label>
                <input class="formInput" resizeToFitContent="true" matInput placeholder="{{userEdit.email}}" formControlName="email" required>
              </mat-form-field>
        </div>
...

组件:

ngOnInit() {
    console.log('in ngoninit');
    this.editBuildForm();
    this.loaduserForEdit();
    
    // this.setEditFormValues();
  }

  loadUserForEdit() {
    const routeSubscription = this.store.select(getCurrentRouteState).pipe(take(1)).subscribe(route => {
        const userId = route.params.userId;
        console.log("route params id: ", userId);
        this.store.dispatch(loadEditeduser({userId}));
        this.store.dispatch(setEditeduserId({userId}));
    });
    this.userObjectUnderEdit = this.store.select(getCurrentuser);
    const userFillSubscriber = this.userObjectUnderEdit.subscribe(user => this.userFormFill = user);
    this.setEditFormValues(this.userFormFill);
    userFillSubscriber.unsubscribe();
    routeSubscription.unsubscribe();
}

const userFillSubscriber = this.userObjectUnderEdit.subscribe(user => this.userFormFill = user); ^ 每当页面刷新时,用户为空。 但是,ngIf 仍然会填充 mat-labels,因此 userObjectUnderEdit 仍然可以正常工作。

【问题讨论】:

  • 能分享一下重载页面时的状态吗?还有 getCurrentUser 选择器?
  • 状态不会在浏览器刷新时持续存在,而是执行 GET 操作以根据路由参数仅检索该用户。
  • 我的意思是调用 ngOnInit 的那一刻。但是我看到你的问题已经解决了!祝你好运。

标签: angular rxjs observable ngrx


【解决方案1】:
    const userFillSubscriber = this.userObjectUnderEdit.subscribe(user => this.userFormFill = user);
    this.setEditFormValues(this.userFormFill);

您正在订阅块内设置属性userFormFill,然后运行

 this.setEditFormValues(this.userFormFill);

我打算借用 T. van den Berg 的代码,但稍作修改:

const userFillSubscriber = this.userObjectUnderEdit.pipe(
    filter(user => !!user), 
    take(1)
).subscribe(user => {
    this.userFormFill = user;
    this.setEditFormValues(this.userFormFill) // add this line inside your subscribe as well
});

【讨论】:

  • 就是这样。感谢您和 T. van den Berg 的帮助。我觉得我尝试了除此之外的所有组合!将来我会更加小心地将任何依赖于发出值的方法调用放在定义该值的块中。
【解决方案2】:

这可能是一个竞争条件问题。 userFillSubscriber 可能在订阅发出任何其他内容然后为 null 之前被取消订阅。通常你只在组件发生故障时取消订阅(onDestroy)。或者你通过 take(x) 来限制排放。

也许这会有所帮助:

const userFillSubscriber = this.userObjectUnderEdit
.pipe(filter(user => !!user), take(1))
.subscribe(user => 
this.userFormFill = user);

这两个 .unsubscribe 函数都是不必要的。订阅在 1 次发射后停止,因为如果使用 take(1) 运算符。

【讨论】:

  • 感谢您的回复。我已经使用 take(1) 运算符进行了尝试,但仍然出现未定义的错误。我也摆脱了我的退订行,结果仍然相同。
猜你喜欢
  • 2021-05-02
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多