订阅子组件的Observable(valueChanges)

时间:2016-08-25 06:00:06

标签: angular observable rxjs5

我认为有一个简单的问题,但我很难找到确认,如果我的解决方案是"正确"

我有一个SearchComponent

的子组件formControl
@Component({
    selector : "my-search",
    inputs : ["placeholder"],
    template : `
      <div class="searchForm">
        <input type="text" [placeholder]="placeholder" [formControl]="search"/>
      </div>
    `
})
export class SearchComponent {

    search = new FormControl();
    public searchValues : Observable<string>;


    constructor() {
        this.searchValues  = this.search.valueChanges
            .debounceTime(400) 
            .distinctUntilChanged(); 
    }

}

我在父组件的模板

中使用它
<div class="col-md-2 sidebar">
    <my-search [placeholder]="'search'"></my-search>
</div>

我现在想要从父级中订阅searchValues Observable。我想出的最好的是:

export class MyListComponent implements AfterContentInit {

    @ViewChild(SearchComponent) searchComponent: SearchComponent;

    constructor(private myService: MyService ) {

    }

    ngAfterContentInit() {
        this.searchComponent.searchValues.subscribe(s=>this.search(s))
    }

    private search(s: string) {
        this.foos = this.myService.find(s); 
    }

    foos: Observable<[Foo]>; // used on a ngFor | async

}

这是推荐的方法吗?是否有更好的方法来定义组件之间的契约(可以使用@Input@Output完成)?

1 个答案:

答案 0 :(得分:2)

您可以轻松地使用@Output。 在搜索组件中,您可以添加如下内容:

@Output() searchEvent: EventEmitter = new EventEmitter();

然后订阅文本更改并(重新)发出它们:

this.search.valueChanges
        .debounceTime(400) 
        .distinctUntilChanged()
        .subscribe((event) => this.searchEvent.emit(event));

之后,您可以在任何父组件中使用输出。无需任何组件引用(ViewChild)。

修改

使用此方法的一种方法是在父组件中将Subject更改为updateStream = new Subject()和事件处理程序(searchEvent) = "updateStream.next($event)"

然后您可以创建Observable,如:

foo = updateStream.flatMap((s) => myService.find(s))