Rxjs订阅在Angular Directive中不起作用

时间:2018-04-06 11:07:19

标签: angular rxjs angular-directive

请考虑以下代码:

  @Component({
  selector: 'cdt-angular-loader',
  templateUrl: 'loader.component.html',
  styleUrls: ['loader.component.scss']
})
export class LoaderComponent implements OnInit, OnDestroy {

  public show = false;
  private subscription: Subscription;

  constructor(private _loaderService: LoaderService) {
  }

  ngOnInit() {
    // subscribe to the service state to hide/show the loader
    this.subscription = this._loaderService.loaderState
      .subscribe((state: LoaderState) => {
        this.show = state.show;
      });
  }

  ngOnDestroy() {
    // unsubscribe
    this.subscription.unsubscribe();
  }
}

订阅按预期工作,只要loaderService调用next(),就会引发订阅。

但是,如果我在Directive而不是Component中使用相同的代码,则永远不会引发订阅:

@Directive({
  selector: '[cdtSaving]'
})
export class SavingDirective implements OnInit, OnDestroy {

  private subscription: Subscription;

  constructor(private _loaderService: LoaderService, private _elRef: ElementRef, private _renderer: Renderer) { }

  ngOnInit() {
   // this._renderer.setElementAttribute(this._elRef.nativeElement, 'disabled', 'true');
    // subscribe to the service state to hide/show the loader
    this.subscription = this._loaderService.loaderState
      .subscribe((state: LoaderState) => {
        alert('state changed:' + state.show);
      });
  }

  ngOnDestroy() {
    // unsubscribe
    this.subscription.unsubscribe();
  }
}
调用

ngOnInit并创建订阅但是从不调用订阅,尽管它在Component中。

它不应该与指令一样工作吗?

[编辑]

关注@ Vikas'注释,我已将我的LoaderService更改为使用BehaviorSubject而不是Subject。现在,在第一次加载指令时会调用subscribe。但是每当服务执行next()时,订阅都不会被调用。我不确定为什么...... 这是loaderService的代码,它的价值......

@Injectable()
export class LoaderService {
  private loaderSubject = new BehaviorSubject<LoaderState>({ show: false});

  public loaderState = this.loaderSubject.asObservable();

  constructor() { }

  show() {
    this.loaderSubject.next(<LoaderState>{ show: true });
  }

  hide() {
    this.loaderSubject.next(<LoaderState>{ show: false });
  }
}

1 个答案:

答案 0 :(得分:0)

我注意到,只要我在顶级模块中使用该指令,即使使用该指令,我的代码也能正常工作。如果我在延迟加载的模块中使用它,它不起作用。

这很奇怪,因为服务是提供给延迟加载的模块,所以从理论上说这应该有效。知道为什么会这样吗?

<强> [编辑]
答案,请参阅Lazy loading : Observable not subscribed

事实证明,订阅者不适用于延迟加载的模块。我不得不将我的服务提升到app模块。现在它有效。