【问题标题】:Subscribe to child component's Observable (valueChanges)订阅子组件的 Observable (valueChanges)
【发布时间】:2017-01-01 10:31:38
【问题描述】:

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

我有一个子组件 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 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)?

【问题讨论】:

    标签: angular observable rxjs5


    【解决方案1】:

    您可以轻松地为此使用@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))
    

    【讨论】:

    • Thanks(!) 这是有道理的,但是它不会公开Observable,然后可以由父级进一步处理。但是我确实喜欢这种简单性,但另一方面,我希望将 observables 视为合同而不是 EventEmitter
    • 它实际上扩展了主题类型,因为它可以同时emit and subscribe to。在父组件中,您可以有一个 Observable/Subject,您可以将事件更改推送到并将其合并/映射到您需要的内容。
    • 感谢您的评论和额外的编辑。这完美地工作并且是“干净的”。我想知道他们是否会更容易订阅@output Source,例如EventEmitter(但老实说,甚至不确定它应该是什么样子)。再次感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    相关资源
    最近更新 更多