简体   繁体   English

在嵌套的 object Angular 中更新 ngrx state

[英]Update ngrx state in nested object Angular

I would be able to update an object nested in another object in my application but i got some problems.我可以在我的应用程序中更新嵌套在另一个 object 中的 object,但我遇到了一些问题。 Let's assume that the entity that I want to update is something like this:假设我要更新的实体是这样的:

{
  {
  "id": 0,
  "name": "Yellow Car",
  "details": {
    "engine": {},
    "ownerInfo": {
      "name": "Luke",
      "lastName": "Cage",
      "email": "l.cage@hisemail.blabla"
    },
  },
  "created": "2018-01-17",
  "lastUpdate": "2020-09-03",
}

I can easily update some part of this entity in this way:我可以通过这种方式轻松更新该实体的某些部分:

let car: Car = {
   ...car,
   ...this.form.value
};

let carUpdate: Update<Car> = {
  id: car.id,
  changes: car
};

this.store.dispatch(carUpdated({carUpdate}));

But in this way I can only update name, created, lastUpdate and I can't update the nested object details .但是这样我只能更新name, created, lastUpdate而不能更新嵌套的 object details What happens if I try to edit the detail object now?如果我现在尝试编辑detail object 会发生什么? Nothing i wanna happens.我不想发生任何事情。

This is the selector:这是选择器:

export const carUpdated = createAction(
    "[Edit Car] Car Updated",
    props<{carUpdate: Update<Car>}>()
);

The effect:效果:

 saveCar$ = createEffect(
        () => this.actions$
        .pipe(
            ofType(CarActions.carUpdated),
            concatMap(action => this.carService.editCar(
                action.carUpdate.changes,
                action.carUpdate.id
            ))
        ),
        {dispatch: false}
    )

The reducer:减速机:

on(CarActions.carUpdated, (state, action) =>
    adapter.updateOne(action.carUpdate, state)),

The service sends to the backend the right data and it's working good without the state management.该服务将正确的数据发送到后端,并且在没有 state 管理的情况下运行良好。 What I am doing now is retrieve the single carObject in this way in the component in the ngOnInit我现在正在做的是在 ngOnInit 的组件中以这种方式检索单个ngOnInit

car$ = this.store.pipe(
   select(selectCar(id))
)

and the selector is:选择器是:

export const selectCar = (id) => createSelector(
    selectAllCars,
    (cars: any) => cars.filter((car) => {
        let filteredCar = car.id == id;
        if(filteredCar) {
            return car;
        }
    }).map(car => car)
);

and then after my edit I can use the dispatch to confirm my edit然后在我编辑之后,我可以使用调度来确认我的编辑

this.store.dispatch(carUpdated({carUpdate}));

but as I said if I try to update the details object i have this但正如我所说,如果我尝试更新细节 object 我有这个

let car: Car = {
       ...car, // the entire car object
       ...this.form.value // only the details
    };
    
    let carUpdate: Update<Car> = {
      id: car.id,
      changes: car //the details are mixed with the car object and not inside the object itself
    };

something like this:像这样的东西:

{
  "id": 0,
  "name": "Yellow Car",
  "engine": {},
  "details": {
  },
  "ownerInfo": {
    "name": "Luke",
    "lastName": "Cage",
    "email": "l.cage@hisemail.blabla"
  },
  "created": "2018-01-17",
  "lastUpdate": "2020-09-03",
}

Is there an easy way to fix this?有没有简单的方法来解决这个问题?

I'll try to provide a general answer which might show techniques on how to update one object with another object.我将尝试提供一个一般性答案,该答案可能会展示如何用另一个 object 更新一个 object 的技术。

If in the form, you only have the details as update (update is Partial<Car["details"]> , you can do this:如果在表格中,您只有更新的details (更新是Partial<Car["details"]> ,您可以这样做:

const update: Partial<Car["details"]> = this.form.value;
const newCar: Car = {
   ...oldCar,
   details: {
      ...oldCar.details,
      ...update
   }

Then there's the possibility that the update is (partial) Car with partial details :然后有可能更新是(部分)带有部分detailsCar

const update: Partial<Car> & { details: Partial<Car["details"]> } = this.form.value;

const newCar: Car = {
   ...oldCar,
   ...update,
   details: {
      ...oldCar.details,
      ...update.details
   }
}

An improbable option is that you have mixed detail and car properties in the update (for whatever reason - you might be doing something wrong).一个不太可能的选择是您在更新中混合了细节和汽车属性(无论出于何种原因 - 您可能做错了什么)。 Then you can pick them by hand.然后你可以手动挑选它们。 Note that this will delete old values if new values are undefined.请注意,如果未定义新值,这将删除旧值。

const update: Pick<Car, 'name' | 'lastUpdate'> & Pick<Car["details"], 'ownerInfo'> = this.form.value;

const newCar: Car = {
   ...oldCar,
   name: update.name,
   lastUpdate: update.lastUpdate,
   name: update.name
   details: {
      ...oldCar.details,
      ownerInfo: details.ownerInfo
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM