在自定义结构指令Angular 6+中使用NGRX Observable

时间:2019-12-02 17:00:35

标签: angular observable ngrx subscription

我正在尝试编写一个使用ngrx存储的自定义结构指令。在商店内部,有一个标志告诉我是否应该显示一些组件。我想让我的自定义指令订阅该商店,并根据该标志为true还是该标志为false来呈现组件,但是该组件具有应呈现的数据。下面的代码:

@Directive({ selector: '[showIfExists]' })
export class ShowIfExistsDirective {

  showEmpty$ = this.store.select(getShowHideState).subscribe((value) => {
    this.showEmpty = value;
  });
  showEmpty: boolean;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private store: Store<AppState>) {
  }

  ngOnDestroy() {
    this.showEmpty$.unsubscribe();
  }

  @Input() set showIfExists(condition: boolean) {
    if (this.showEmpty || (!this.showEmpty && condition)) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }
}

我最终看到的是订阅正确更新了我的showEmpty属性,但是,除非set showIfExistsshowEmpty,否则showEmpty不会对{{1}}的更改做出响应。真正。

1 个答案:

答案 0 :(得分:1)

您将需要在订阅中创建或清除视图。我建议您从输入中创建另一个Observable(BehaviorSubject)。

@Directive({ selector: '[showIfExists]' })
export class ShowIfExistsDirective {

  showEmpty$: Observable<boolean> = this.store.select(getShowHideState);
  showIfExists$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private store: Store<AppState>) {

    combineLatest([this.showEmpty$, this.showIfExists$]).pipe(
      distinctUntilChanged(),
      map(([showEmpty, showIfExists]) => showEmpty || condition), // !showEmpty is btw redundant
      // don't forget to unsubscribe your way
    ).subscribe(activate => {
      if (activate) this.viewContainer.createEmbeddedView(this.templateRef)
      else this.viewContainer.clear();
    });
  }

  @Input() set showIfExists(condition: boolean) {
    this.showIfExists$.next(condition);
  }
}