【问题标题】:Why subscription not working in constructor?为什么订阅在构造函数中不起作用?
【发布时间】:2021-02-19 12:24:13
【问题描述】:

我有以下课程:

我尝试保存 prev 和 current state,并通过用户点击替换 prev state on current。

@Injectable({
  providedIn: "root",
})
export class PortalBridgeService {
  private portalsSubject = new Subject<Portal>();
  private prev: Portal;

  readonly portals$ = this.portalsSubject.pipe(
    startWith(portalDefault()),
    pairwise(),
    map(([prev, current]) => ({ prev, current }))
  );
  // States
  readonly currentPortal$ = this.portals$.map((value) => value.current);
  readonly prevPortal$ = this.portals$.map((value) => value.prev);

  constructor() {
    this.prevPortal$.subscribe((prev) => (this.prev = prev));
  }

  activatePortal(type: PortalType) {
    try {
      const portal = portalByType(type);

      if (!portal) throw `There is not found portal with type ${type}`;

      this.setPortal(portal);
    } catch (e) {
      console.error(e);
    }
  }

  setPortal(portal: Portal) {
    this.portalsSubject.next(portal);
  }

  disposePortal() {
    if (this.prev) {
      this.setPortal(this.prev);
    }
  }
}

模板是:

<ng-template [cdkPortalOutlet]="currentPortal$ | async"></ng-template>

尽管startWith 发出第一个值,但为什么我没有在this.currentPortal$.subscribe((res) =&gt; console.log(res)); 中获得值?

我在模板中使用异步:

currentPortal$ | async

我试图将其简化为:

export class PortalBridgeService implements OnInit {
  public portalsSubject = new BehaviorSubject<Portal>(portalDefault());

  ngOnInit() {
    this.portalsSubject
      .pipe(
        pairwise(),
        map(([prev, current]) => ({ prev, current }))
      )
      .subscribe((data) => console.log(data));
  }
}

.subscribe((data) =&gt; console.log(data)); 不工作!

【问题讨论】:

  • 根据您之前的问题,您不是说订阅需要附加到click 事件吗?目前没有任何东西可以触发订阅。某些东西必须触发 portalsSubject 主题。
  • 我是通过模板中的currentPortal$ | async 触发的。 readonly currentPortal$ = this.portals$.map((value) =&gt; value.current)
  • async 是一种在模板中订阅的奇特方式。它与构造函数中的订阅没有太大区别。需要将一些值发送到可观察对象,例如this.currentPortal$.next(...)。同样,您是否仍希望将此可观察对象附加到元素的单击事件?如果是,请出示模板。
  • 我已经用包括 temaplte 在内的完整代码更新了我的问题
  • 另外我想知道如何将值从prevPortal$ 分配给currentPortal$

标签: angular rxjs


【解决方案1】:

此代码不正确,打字稿是否给您任何错误?

readonly prevPortal$ = this.portals$.map((value) => value.prev);

我想你想要:

readonly prevPortal$ = this.portals$.pipe(map(v => v.prev));

【讨论】:

    【解决方案2】:

    管道运算符永远不会强制 Observable 发出值。在某些时候,您必须调用 next() 来启动该过程

    export class PortalBridgeService {
      constructor() {
        this.currentPortal$.subscribe((res) => console.log(res));
        this.portalsSubject.next(); // <---- do this here
      }
    }
    

    【讨论】:

    • 如果用BehaviorSubject代替主题呢?
    • 我认为这不会改变您的根本问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    • 2022-07-29
    • 1970-01-01
    • 2023-03-17
    • 2022-01-04
    • 2019-04-30
    相关资源
    最近更新 更多