Angular Materials模态:为什么在subscribe中未定义我的变量,而在map方法中未定义我的变量?

时间:2018-09-06 12:16:22

标签: angular rxjs

我正在将Angular 6与Angular Materials一起使用。

在我的模态中,我有:

<div style="display: flex; justify-content: space-between" >
  <button color="primary" mat-button [mat-dialog-close]="false">Cancel</button>
  <button color="primary" mat-button [mat-dialog-close]="gizmo">{{inEditMode === true ? "Save" : "Add"}}</button>
</div>

因此模态将返回false(如果用户单击“取消”)或返回gizmo对象(如果用户单击“添加”)。

在调用模式的类中,我有以下代码。 当我调试x变量时,确实包含gizmo对象。但是,一旦完成x,则在订阅中未定义x。这是为什么? x是否不应该像地图中那样包含小控件?

addGizmo() {
    let gizmo = new Gizmo();
    this.tagSubject.next(gizmo);

    let dialogEdit = this.dialog.open(DialogGizmo,
      {
        width: "300px",
        data: { },
      });

    dialogEdit.afterClosed()
      .pipe(map(x => {
        if (x !== false) {
          gizmo.value = x.GizmoValue;
          gizmo.description = x.GizmoDescription;
        }
      }))
      .subscribe(x => {
      if (x !== undefined) {
        this.dataCatalogService.addGizmo(gizmo)
        .subscribe(
          () => this.loadGizmos(),
          error => this.handleError(error)
        );
      }
    });
};

2 个答案:

答案 0 :(得分:2)

您的map管道返回未定义。 在地图的末尾添加return x

dialogEdit.afterClosed()
  .pipe(map(x => {
    if (x !== false) {
      gizmo.value = x.GizmoValue;
      gizmo.description = x.GizmoDescription;
    }
    return x;  // THIS LINE
  }))
  .subscribe(x => {
  if (x !== undefined) {
    this.dataCatalogService.addGizmo(gizmo)
    .subscribe(
      () => this.loadGizmos(),
      error => this.handleError(error)
    );
  }
});

map管道具有价值,应该返回您需要传递给其他管道的任何结果。 了解有关map here

的更多信息

P.S。似乎您实际上不需要这里的map管道是因为您没有转换输入值。看看do / tap operator

答案 1 :(得分:0)

根据@ArtemArkhipov的回答,您没有在map函数中返回任何内容。

虽然它可以解决您的问题,但我认为您可以像这样提高代码的可读性

<!-- Not returning something will return '' -->
<button color="primary" mat-button mat-dialog-close>Cancel</button>
<button color="primary" mat-button [mat-dialog-close]="gizmo">{{inEditMode === true ? "Save" : "Add"}}</button>
dialogEdit.afterClosed()
  .pipe(
    // filter : if the response is falsy, don't go further ('' is falsy)
    filter(res => !!res),
    // tap the answer, because you don't want to change it, only update your variable
    tap(x => {
      gizmo.value = x.GizmoValue;
      gizmo.description = x.GizmoDescription;
    }),
    // Use mergeMap to chain another HTTP call and get rid of one subscribe
    mergeMap(x => this.dataCatalogService.addGizmo(gizmo))
  ).subscribe(
    () => this.loadGizmos(),
    error => this.handleError(error)
  )
);

这可以减少代码并提高其可读性。没有评论,它会给出

dialogEdit.afterClosed()
  .pipe(
    filter(res => !!res),
    tap(x => {
      gizmo.value = x.GizmoValue;
      gizmo.description = x.GizmoDescription;
    }),
    mergeMap(x => this.dataCatalogService.addGizmo(gizmo))
  ).subscribe(
    () => this.loadGizmos(),
    error => this.handleError(error)
  )
);