订阅子组件的 Observable(valueChanges)

Subscribe to child component's Observable (valueChanges)

我认为有一个简单的问题,但如果我的解决方案是 "correct"

,我很难找到确认

我有一个带有 formControl

的子组件 SearchComponent
@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 来完成)?

您可以轻松地为此使用@Output。 在搜索组件中,您可以添加一个:

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

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

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

之后你就有了可以在任何父组件中使用的输出。无需任何组件引用 (ViewChild)。

编辑

使用它的一种方法是在父组件中有一个主题,您将更改推送到 updateStream = new Subject() 和事件处理程序 (searchEvent) = "updateStream.next($event)".

然后你可以像这样创建 Observable:

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