1

如果我在打字稿中有以下界面

interface Member {
   readonly id: number;
   readonly name: string;
   readonly email: string;
   groups: <ReadonlyArray>Group
}

interface Group {
   readonly id: number;
   readonly name: string;
   readonly active: boolean;
}

数据看起来像这样

member {
   id: 1,
   name: 'John Doe',
   email: 'junk@junk.com'
   groups: [
      { id: 1, name: 'Group 1', active: true}
      { id: 2, name: 'Group 2', active: false}
      { id: 3, name: 'Group 3', active: false}
   ]
}

如果我想将它存储在 akita/state 中并允许它是可变的(即,也许用户想要单击一个复选框来表示“Group 2”现在处于活动状态并且我需要更新 akita/state),我该怎么做整个对象的副本,因此它不是不可变的(在插入秋田/状态之前)?

好的,我想在阅读以下评论后编辑我的问题。

我将以下代码插入我的秋田商店

  loadMemberById(memberId: number) {
    const request$ = this.membersDataService.getById(memberId).pipe(
      tap(response => this.membersStore.upsert(response.id, response)),
      tap(response => this.membersStore.upsert(response.id, { groups: { 
         ...response.groups } })),
      tap(response => this.membersStore.setHasCache(true))
    );

    return cacheable(this.membersStore, request$);
  }

VS 在抱怨state.member.groups里面arrayUpdate

  update(groupId: number, value: boolean): Observable<void> {
    const observer = this.groupsDataService.update(groupId, value);

    observer.subscribe(() => {
      this.sessionStore.update(state => {
        return {
          member: {
            ...state.member,
            groups: arrayUpdate(state.member.groups, data => data.groupId === 
                groupId, {
                    active: value
            })
          }
        };
      });
    });

谢谢jonpfl

4

3 回答 3

1

immerjs - 只读删除:

谨慎使用,因为这允许您编辑可能不会更改的值

最好与扩展运算符/object.assign 结合使用

type AtomicObject =
    | Function
    | Promise<any>
    | Date
    | RegExp
    | Boolean
    | Number
    | String

type Draft<T> = T extends AtomicObject
    ? T
    : T extends ReadonlyMap<infer K, infer V> // Map extends ReadonlyMap
    ? Map<Draft<K>, Draft<V>>
    : T extends ReadonlySet<infer V> // Set extends ReadonlySet
    ? Set<Draft<V>>
    : T extends WeakReferences
    ? T
    : T extends object
    ? {-readonly [K in keyof T]: Draft<T[K]>}
    : T
于 2020-07-31T20:07:58.730 回答
0

使用扩展运算符作为副本

const oldState =....
const groupToadd = {...somegroup...};
const newState = {
... oldState
groups: oldState.groups.concat(groupToAdd)

}
于 2020-07-31T20:06:32.467 回答
0

尝试这个:

mutableGroup = { ...readOnlyGroup }

这三个点是展开或休息运算符。此运算符允许扩展对象或数组并返回内部变量,如函数的参数。这也可用于在不更改其值的情况下制作实例的副本。所以在这种情况下,它与 readOnly 条件分离并复制该值。

于 2020-07-31T20:10:20.690 回答