【问题标题】:Observable and EventEmitter for pass data parents (Angular)用于传递数据父级的 Observable 和 EventEmitter (Angular)
【发布时间】:2020-01-30 23:27:04
【问题描述】:

我有以下结构:

  • 主要组件(通过 item-service 渲染项目)
    • 面板组件(包含搜索组件)
      • SerachByTitle 组件(包含标题项的输入字段)
      • SerachBySomething 组件(包含某物项的某物输入字段)
  • 物品服务

当用户在 SerachByTitle 组件中输入标题时,我想在主组件中呈现项目(适合搜索请求)。

为此,我使用了 EventEmitter: Panel-component、SerachByTitle-component 和 SerachBySomething-component 都有装饰器@Output。

SerachByTitle 和 SerachBySomething 将数据传递给 Panel-component,Panel-component 形成单个 object-params,然后传递给 Main-component。

当用户输入标题时,我遇到了一个问题——在每个 keyup 主组件重新渲染项目之后。我尝试使用组合:debounceTime(timeDelay)、 distinctUntilChanged()、switchMap(),但对我没有帮助。

我做错了什么?

对不起我的英语不好:(

UPD:为了了解我的情况,我添加了example。 对于主要组件,我使用了组合:debounceTime()、 distinctUntilChanged()、switchMap()。但不存在搜索延迟。

【问题讨论】:

  • 你能写出一些你工作过的代码,作为我们帮助你做一个具体例子的基础吗?
  • Exomus,谢谢!我添加了指向 stackblitz 的链接

标签: angular observable angular8 eventemitter


【解决方案1】:

这是您的代码 (main.component.ts):

searchChangedHandler(filter){
  this.itemService.searchItems(filter).pipe(
      debounceTime(1300),
      distinctUntilChanged(),
      switchMap((items) => this.listItems = items),
    ).subscribe();
}

问题是你在不正确的地方应用了 debounceTime+distinctUntilChanged。这是您项目中发生的事情的简化图:

      #1                   #2                       #3                                
oninput event ---> ItemService.search(term) ----> of(items) ---> ...

                           #4                                      #5
... ---> pipe(debounceTime(1300)+distinctUntilChanged) ---> this.listItems = items 

基本上,您在每次击键时运行搜索,然后对搜索结果应用 debounceTime+distinctUntilChanged。 这没什么意义,因为您显然想限制发送到您的 ItemService 的请求数量,因此您必须申请 调用 ItemService 之前的 debounceTime

(您可能想知道为什么即使在 ItemService.search 的结果中也没有看到 1300 延迟,但您会立即看到更改。原因是上图中第 3 步中的 of(items) 创建一个新的 observable 立即完成,因此不应用延迟)。

所以这是处理这个问题的正确方法:

oninput event ---> pipe(debounceTime(1300)+distinctUntilChanged) ----> ...

... ----> ItemService.search(term) ----> this.listItems = items 
  private searchStream = new Subject<any>();

  ngOnInit() {
    this.searchStream
      .pipe(
        debounceTime(1300),
        distinctUntilChanged(),
        switchMap(filter => this.itemService.searchItems(filter))
      )
      .subscribe(items => this.listItems = items);
  }

  searchChangedHandler(filter){
    this.searchStream.next(filter);
  }

这是更正后的项目:https://stackblitz.com/edit/angular-iopeep

【讨论】:

  • 太棒了!但是您忘记为面板组件指定一些重要的更改:对于 this.searchChanged.emit() - 您创建新对象。据我了解,这是由于 distinctUntilChanged() 造成的。谢谢你的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多