有没有办法订阅Observable
@Input
?
例如:
export class MyComponent implements OnInit {
@Input() results: Observable<string[]>;
constructor() {
this.results.subscribe(value => ...);
}
}
在此示例中,我无法订阅observable,因为它是null
...
答案 0 :(得分:5)
您应该实现OnChanges
并在更改时订阅输入。
export class MyComponent implements OnChanges {
@Input() results: Observable<string[]>;
constructor() { }
ngOnChanges(changes){
if(changes["results"] && this.results){
this.results.subscribe(value => ...);
}
}
}
这将允许您在Observable可用时订阅它,并在Observable引用更改时随时重新订阅它。您可能需要考虑取消订阅旧实例,具体取决于您的用例。
答案 1 :(得分:3)
我真的不喜欢将Observable
作为@Input
本身传递,但我非常喜欢将标准@Input()
转化为 Observable
。这是一种更加灵活的方法,可以更轻松地在组件和外部之间保持更清晰的边界。一旦您开始订阅从父组件传入的可观察对象,就会带来很多不必要的复杂性。
这是我发现的最佳方法,并且我越来越多地使用RxJS并看到可以完成的工作。有点笨拙,但我确实在为将来提供类似的东西提供更好的框架支持。
// 'floating' input parameter, with default value of 'false'
@Input('floating') set floating(floating: boolean) { this.floating$.next(floating); };
private floating$ = new BehaviorSubject<boolean>(false);
然后在父组件中可以传递布尔值:
<app-magic-box [floating]="true"></app-magic-box>
<app-magic-box [floating]="shouldFloatMagicBox"></app-magic-box>
如果您要发送的内容作为Observable
存储在“外部”,则一定要使用异步管道将其发送。这样,可以将特定属性的订阅和清理工作留给父组件(和框架),而不是尝试在魔术盒组件内部进行处理。
<app-magic-box [floating]="float$ | async"></app-magic-box>
现在您可以在魔术盒组件内部使用此可观察的对象。请注意,它的默认值为false
,因此,如果我们从未设置floating
,它仍然可以使用。
public showRabbit$: Observable<boolean>;
ngOnInit()
{
// (only run this initialization once)
// subscribe directly if you wish, but keep a reference to dispose in ngOnDestroy
this.floating$.subscribe(floating => ...);
// we can also create a new observable based on our input parameters
// with whatever RxJS you want. if a new input value is set it will
// propagate through all the pipes
// show a rabbit when not floating (why not!)
this.showRabbit$ = this.floating$.pipe(map(floating => floating == false));
}
现在,您的魔术框中还有另一个可观察的内容,您可以在模板中使用它。您会发现“异步”管道四处传播,但这很好。
<img *ngIf="showRabbit$ | async" src="./rabbit.png"/>
重要说明:如果要将其用作@HostBinding
,则必须执行以下操作:
@HostBinding("attr.floating")
get attr_floating() { return this.floating$.value; }
如果您确实对在BehaviorSubject上访问value
有问题,请给我一个更好的解决方案;-)在我这里做的事情中,我对此没有任何疑问。
我真的希望将来该框架将具有类似@InputObservable
的功能,并且其功能比我们今天所能达到的神奇。