为了账号安全,请及时绑定邮箱和手机立即绑定

RxJs 行为数组允许设置/订阅单个项目的主题

RxJs 行为数组允许设置/订阅单个项目的主题

波斯汪 2022-09-16 21:29:04
我想使用一个Constorsubject来存储一个对象数组,并有一种方法可以轻松地更新(下一个?)该数组的单个项目,而不必更新整个数组。我还想提供一种简单的方法来订阅对该数组的特定项的更改。我知道这可以用过滤器完成,但更简单的方法会很好...这可能吗?我目前正在使用我创建的这个版本(我不知道这是否是最好的方法),它也将其内容保存到localtorage:export class LocalStorageBehaviorSubject<T, Y = T> {  private _data: BehaviorSubject<T>;  public asObservable() {    return this._data.asObservable();  }  public next(data: T) {    if(this.expirationFn !== null) {      data = this.expirationFn(data);    }    localStorage.setItem(this.key, JSON.stringify(data));    this._data.next(data);  }  public nextItem(item: Y) {    if (!Array.isArray(this._data.getValue())) {      throw "Type is not an Array";          }    let dados: any = (<any>this._data.getValue()).slice();    if (dados.some(r => r[this.id] === item[this.id])) {      dados = dados.map(r => r[this.id] === item[this.id] ? item : r);    } else {      dados.push(item);    }    if(this.expirationFn !== null) {      dados = this.expirationFn(dados);    }    localStorage.setItem(this.key, JSON.stringify(dados));    this._data.next(<any>dados);  }  public removeItem(id) {    if (!Array.isArray(this._data.getValue())) {      throw "Type is not an Array";          }    let dados: any = (<any>this._data.getValue()).slice();    dados = dados.filter(r => r[this.id] !== id);    localStorage.setItem(this.key, JSON.stringify(dados));    this._data.next(<any>dados);  }  public removeExpiredData(){    let data = this.loadFromStorage();    if (data) {      if(this.expirationFn !== null) {        data = this.expirationFn(data);      }      this._data.next(data);    }  }  public getValue() {    this.removeExpiredData();    return this._data.getValue();  }  public getItem(id): Y {    if (!Array.isArray(this._data.getValue())) {      throw "Type is not an Array";          }我希望这将是一种更简单的方法...谢谢
查看完整描述

1 回答

?
慕虎7371278

TA贡献1802条经验 获得超4个赞

我还想提供一种简单的方法来订阅对该数组的特定项的更改。我知道这可以用过滤器完成,但更简单的方法会很好...


您可以使用地图运算符和内部 lambdaarray.find



const mockStorage = {

  values: {},

  setItem(key, value) {

    this.values[key] = value;

  },

  getItem(key) {

    return this.values[key]

  },

  clearItem(key) {

    this.values[key] = undefined;

  }

}


class LocalStorageBehaviorSubject {


  constructor(key, defaultValue) {

    this.key = key;

    this._data = new rxjs.BehaviorSubject(defaultValue);

  }


  nextItem(item) {

    const list = this._data.value;

    const itemIndex = list.findIndex(pr => pr.id === item.id);

  

    this._data.next([

      ...list.slice(0, itemIndex),

      {

        ...(list[itemIndex] || {}),

        ...item

      },

      ...list.slice(itemIndex + 1)

    ]);

  }


  removeItem(id) {

    this._data.next(this._data.value.filter(pr => pr.id !== id));

  }


  getItem(id) {

    return this.asObservable()

      .pipe(

        rxjs.operators.map(values => values.find(pr => pr.id === id) || null), 

        rxjs.operators.distinctUntilChanged());

  }


  asObservable() {

    return this._data.asObservable().pipe(

      rxjs.operators.tap(values => {

        if (values && values.length) {

          mockStorage.setItem(this.key, JSON.stringify(values));

        }

        else {

          mockStorage.clearItem(this.key);

        }

      }))

  }


}


const localStorageBehaviorSubject = new LocalStorageBehaviorSubject('items', []);


localStorageBehaviorSubject

  .getItem(1)

  .subscribe(item => {

    console.log(item);

  })

  

localStorageBehaviorSubject.nextItem({id: 1, value: 'test'})

localStorageBehaviorSubject.nextItem({id: 1, value: 'test1'})

localStorageBehaviorSubject.nextItem({id: 2, value: 'test2'})

localStorageBehaviorSubject.nextItem({id: 3, value: 'test3'})

localStorageBehaviorSubject.removeItem(2);

localStorageBehaviorSubject.removeItem(1);

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.js"></script>


查看完整回答
反对 回复 2022-09-16
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信