请考虑以下代码:
@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 });
}
}
答案 0 :(得分:0)
我注意到,只要我在顶级模块中使用该指令,即使使用该指令,我的代码也能正常工作。如果我在延迟加载的模块中使用它,它不起作用。
这很奇怪,因为服务是提供给延迟加载的模块,所以从理论上说这应该有效。知道为什么会这样吗?
<强> [编辑] 强>
答案,请参阅Lazy loading : Observable not subscribed
事实证明,订阅者不适用于延迟加载的模块。我不得不将我的服务提升到app模块。现在它有效。