【问题标题】:How do I add autoincrementing ids to a dynamically sized observable array?如何将自动递增的 id 添加到动态大小的可观察数组?
【发布时间】:2021-03-10 17:51:01
【问题描述】:

我用的是callbags,但是逻辑和RxJS一样。

我正在制作一个可以添加和删除的可观察列表。我想要自动递增的 id。我不知道将 ID 附加到项目的正确逻辑。

这是一个仅添加事件的简化示例:

import { flatten, map, merge, pipe, scan } from 'callbag-basics';
import just from 'callbag-of';
import remember from 'callbag-remember';
import subscribe from 'callbag-subscribe';

const addEvents = remember(just('add-event', 'add-event')); // remember is shareReplay(1)
const itemIds = pipe(
  addEvents,
  scan((acc) => acc + 1, 1),
);
const initialReducers = just(() => [{ id: 1, data: 'foo' }]);
const addReducers = pipe(
  addEvents,
  map(() => pipe(
    itemIds,
    map((id) => ({ id, data: 'bar' })),
  )),
  flatten,
  map((item) => (prevState) => prevState.concat(item)),
);
const reducers = merge(initialReducers, addReducers);
const states = pipe(
  reducers,
  scan((acc, reducer) => reducer(acc), null),
);

pipe(
  states,
  subscribe((state) => {
    // Expected
    // [{ id: 1, data: 'foo' }]
    // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}]
    // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}, { id: 3, data: 'bar'}]
    console.log(state);
    // Actual
    // [{ id: 1, data: 'foo' }]
    // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}]
    // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}, { id: 2, data: 'bar'}]
    // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}, { id: 2, data: 'bar'}, { id: 3, data: 'bar'}]
  }),
);

每个附加项目的 id 从头开始​​。相反,我希望 id 与添加的项目数相匹配。本质上,问题是将运行的事件总数附加到事件数据的转换中。如何将自动递增的 id 添加到动态大小的可观察数组?

无需将答案放入 callbags 形式。我可以阅读 RxJS。谢谢。

编辑:我安装了 RxJS 来转换示例:

const rxjs = require('rxjs');
const { map, mergeMap, scan, shareReplay } = require('rxjs/operators');

const addEvents = rxjs.of('add-event', 'add-event').pipe(
  shareReplay(1),
);
const itemIds = addEvents.pipe(
  scan((acc) => acc + 1, 1),
);
const initialReducers = rxjs.of(() => [{ id: 1, data: 'foo' }]);
const addReducers = addEvents.pipe(
  mergeMap(() => itemIds.pipe(
    map((id) => ({ id, data: 'bar' })),
  )),
  map((item) => (prevState) => prevState.concat(item)),
);
const reducers = rxjs.merge(initialReducers, addReducers);
const states = reducers.pipe(
  scan((acc, reducer) => reducer(acc), null),
);

states.subscribe((state) => {
  // Expected
  // [{ id: 1, data: 'foo' }]
  // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}]
  // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}, { id: 3, data: 'bar'}]
  console.log(state);
  // Actual
  // [{ id: 1, data: 'foo' }]
  // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}]
  // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}, { id: 2, data: 'bar'}]
  // [{ id: 1, data: 'foo' }, { id: 2, data: 'bar'}, { id: 2, data: 'bar'}, { id: 3, data: 'bar'}]
});

【问题讨论】:

    标签: javascript rxjs observable reactive-streams


    【解决方案1】:

    不熟悉 callbag 库,但你有没有尝试过:

      map(() => pipe(
       itemIds,
       map((id,index) => ({ id + index, data: 'bar' })),
      )),
    

    【讨论】:

    • 我不想使用索引。在实际代码中,我还删除了项目。如果我依赖它,索引会产生重复。我需要跟踪所有事件。
    猜你喜欢
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 2019-01-22
    • 2019-06-11
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 2013-05-17
    相关资源
    最近更新 更多