2016-08-25 129 views
1

我認爲有一個簡單的問題,但我有一個很難找到的確認,如果我的解決辦法是「正確的」訂閱子組件的可觀察(valueChanges)

我有一個孩子組件SearchComponentformControl

@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可從父母內部觀察。最好的我想出的是:

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)?

回答

2

您可以輕鬆使用@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)"父組件一個主題

編輯

的一種方式。

然後,您可以創建可觀察到這樣的:

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

由於這是有道理的,但是它不公開的'Observable',其然後可以進一步爲例如由父處理(!)。然而,我喜歡這種簡單性,但另一方面會喜歡看到observables作爲契約而不是'EventEmitter' – jen

+0

它實際上擴展了Subject類型,因爲它可以[發出和訂閱](https:// angular.io/docs/ts/latest/api/core/index/EventEmitter-class.html)。在父組件中,您可以擁有一個Observable/Subject,您可以將事件更改推送到合併/映射到您需要的位置。 –

+0

感謝您的評論和額外的編輯。這工作完美並且「乾淨」。我想知道他們是否會更容易訂閱一個'@ output''Source',比如'EventEmitter'(但是老實說,不知道應該看起來像什麼)。再次感謝你的幫助 :) – jen