【问题标题】:How to check json object with distinctUntilChanged before subscribing to observable如何在订阅 observable 之前使用 distinctUntilChanged 检查 json 对象
【发布时间】:2018-08-16 13:51:27
【问题描述】:

我只想在我从观察者主题收到的 JSON 对象的值发生变化时订阅 observable:

 searchedName = '';


  filters = {
  "page": 1,
  "perPage": 10,
  "sortOrder": "asc",
  "tag": "allUsers",
  "sortBy": "firstname"
}
  getUsers(e)
  {
    console.log("searched")
    const searchedKeyword = this.searchedName.trim();
    if(searchedKeyword !== '')
    this.filters['name'] = searchedKeyword
    this._service.triggerCallForUsers(this.filters)
  }
   ngOnInit()
{
  //Initially called to load users..
   this._service.triggerCallForUsers(this.filters)

   //Subscribe to fetch users
    this._service.startFetchingUsers$
      .distinctUntilChanged()
      .subscribe((filters) => {
        console.log("filters", filters)
        if (filters) {
          this._service.getUsersByFilter(filters)
            .subscribe(
              users => {
                console.log('users', users);

              },
              error => {}
            );
        }

      })
}

过滤器在哪里:

这可能吗?

尝试解决如下:

.distinctUntilChanged((a, b) => {
  console.log('compare', b['name'], a['name'], b['name'] === a['name']);
  return a === b
})

// 第一次订阅时 输出:- 比较没有输出

//当我添加 's' searchedName 字段时,即发送到的过滤器 next() 将包含

过滤器['name']

输出:- 比较 s undefined false

// 如果我将 searchedName 更改为 'sd':

输出:- 比较 sd sd true。

更新:

   <input type="text" (keyUp.enter)="getUsers($event)" [(ngModel)]="searchedName">

服务:

在服务中,我在 observable 上调用 next():

private startFetchingUsers = new BehaviorSubject < any > (null);
startFetchingUsers$ = this.startFetchingUsers.asObservable();



triggerCallForCareGroup(filter) {

    this.startFetchingUsers .next(filter);
  }

【问题讨论】:

  • 你用的是什么版本的 rxjs?
  • "rxjs": "5.5.6" 根据我的 package.json

标签: angular rxjs angular2-observables


【解决方案1】:

如果您需要深度相等,请尝试使用来自 lodash 的 isEqual

另外,您在 subscribe 中的逻辑过多 - 考虑使用 do/tap 处理副作用,使用 mergeMap 合并其他 Observables。

import { isEqual } from 'lodash';

this._service.startFetchingUsers$
    .distinctUntilChanged(isEqual)
    .do(filters => console.log("filters", filters))
    .mergeMap(filters => this._service.getUsersByFilter(filters))
    .do(users => console.log('users', users))
    .subscribe({
        error(error) {
            console.error(error);
        },
    });

当我在过滤器 json 中更改名称参数时,我得到更新的值 a['name'] 和 b['name'] 相同。

这表明您的代码中的其他地方也可能存在问题。可以分享一下你调用startFetchingUsers.next(newFilters)的代码吗?

更新

您正在改变this.filters 对象,因此您看不到更改,因为a === b 始终成立。对象本身是一样的!像这样使用浅拷贝:this._service.triggerCallForUsers({ ...this.filters })

【讨论】:

  • m1ch4ls 谢谢。我已经更新了帖子。你能复习一下吗?
  • 当我更改对象的键时,a['name'] 不应该等于 b['name']。他们为什么都打印相同的输出?如果对象键相同,并不意味着对象键值相同。我无法理解。在需要研究如何使用它之前,我从未使用过扩展语法。感谢帮助!非常感谢。
  • 好吧,distinctUntilChanged 持有对最后一个对象的引用,您更改它并再次提供它 - 因此持有和提供的对象是相同的。这是相同的参考...
猜你喜欢
  • 2018-03-13
  • 2013-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
相关资源
最近更新 更多