订阅可观察输入

时间:2017-02-02 19:04:54

标签: angular

有没有办法订阅Observable @Input

例如:

export class MyComponent implements OnInit {
  @Input() results: Observable<string[]>;
  constructor() {
     this.results.subscribe(value => ...);
  }    
}

在此示例中,我无法订阅observable,因为它是null ...

2 个答案:

答案 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的功能,并且其功能比我们今天所能达到的神奇。

相关问题