开发者问题收集

ngrx 使用调度时从列表中删除项目

2020-04-24
4135

我有 angular 8 应用程序。我正在使用 ngrx 进行状态管理。

但问题是,如果我尝试删除项目,它会重定向到其他选项卡。并且不删除项目。

所以我有这个:

reducer:

const intialState: Tutorial = {
  name: 'initial State',
  url: 'http://google.com'
};

export function tutorialReducer(state: Tutorial[] = [intialState], action: TutorialActions.Actions) {
  switch (action.type) {
    case TutorialActions.ADD_TUTORIAL:
      return [...state, action.payload];
    case TutorialActions.DELETE_TUTORIAL:
      state.splice(action.payload, 1);
      return state;
    default:
      return state;
  }
}

动作:

export class AddTutorial implements Action {
  readonly type = ADD_TUTORIAL;

  constructor(public payload: Tutorial) {}
}

export class RemoveTutorial implements Action {
  readonly type = DELETE_TUTORIAL;

  constructor(public payload: number) {}
}

export type Actions = AddTutorial | RemoveTutorial;

并删除模板:

<div class="right" *ngIf="tutorials$">
  <h3>Tutorials</h3>

  <ul>
    <li (click)="delTutorial(i)" *ngFor="let tutorial of tutorials$ | async; let i = index">
      <a [href]="tutorial.url" target="_blank">{{ tutorial.name }}</a>
    </li>
  </ul>
</div>

和 ts 代码:

export class ReadComponent implements OnInit {

  tutorials$: Observable<Tutorial[]>;

  constructor(private store: Store<AppState>) {
  this.tutorials$ = this.store.select('tutorial');
  }

 delTutorial(index){
    this.store.dispatch(new TutorialActions.RemoveTutorial(index));
  }
  ngOnInit() {
  }

}

和 app.module.ts:

 imports: [
    BrowserModule,
    StoreModule.forRoot({tutorial: tutorialReducer}),
    AppRoutingModule
  ],

但是它不会删除项目,但实际上会打开一个新选项卡。

然后我收到此错误:

core.js:9110 ERROR TypeError: Cannot assign to read only property '5' of object '[object Array]'
    at Array.splice (<anonymous>)
    at tutorialReducer (tutorial.reducers.ts:16)
    at combination (store.js:303)
    at store.js:1213
    at store.js:38

所以我必须改变什么?这样您就可以从列表中删除一个项目?

谢谢

2个回答

我建议做以下事情:

  • 您应该避免直接改变状态。
  • 创建状态的副本,然后执行操作
  • 还有一件事要记住,splice 将第一个参数作为要删除的元素的索引。
  • 从数组中找到有效负载或项目的索引
  • 然后使用此索引拼接数组元素。

  • 例如:

var array = [...state]; // make a separate copy of the array or state
  var index = array.indexOf(your_payload_toberemoved)
  if (index !== -1) {
    array.splice(index, 1);
   return array
  }   

我希望这些要点对您有所帮助。

Neha Tawar
2020-04-24

状态是不可变的。因此,您无法在 Reducer 中更改状态。 您必须返回新的修改值,而不更改当前状态。

case TutorialActions.DELETE_TUTORIAL:
  let newState = [...state]; 
  newState.splice(action.payload, 1);
  return newState;
Kateryna Savenko
2020-04-24