Guide NgRx
  • Sommaire
  • Introduction
  • De Redux à NGRX
  • Getters & create todo
  • Delete todo
  • Un peu de refacto
  • Select & Update Todo
  • API
  • Load Guard & DevTools
  • Create Todo version 2
  • Delete Todo V2
  • Update Todo v2
  • Les action de type ERROR
  • @Ngrx/Entity
  • Bonus stage
  • Advanced testing
Powered by GitBook
On this page
  • [Début de la branche step-5]
  • Suite >>

Was this helpful?

Select & Update Todo

[Début de la branche step-5]

Rajouter une propriété dans notre TodoListState afin de conserver une todo, ce qui permettra la mise à jour de celle-ci. Cela implique de modifier l'interface, les actions et le reducer.

models/todo.ts

export interface TodoListState {
    // [...]
    selectTodo: Todo
}

Ajouter les actions SELECT & UPDATE qui ont un paramètre de type Todo.

store/actions/todo-list.action.ts

export namespace TodoListModule {
    export enum ActionTypes {
        // [...]
        SELECT_TODO = '[todoList] Select Todo',
        UPDATE_TODO = '[todoList] Update Todo'
    }
    // [...]
    export class SelectTodo {
        readonly type = ActionTypes.SELECT_TODO;
        constructor(payload: Todo){}
    }

    export class UpdateTodo {
        readonly type = ActionTypes.UPDATE_TODO;
        constructor(payload: Todo){}
    }
    // [...]
    export type Actions = InitTodos
    | SelectTodo
    | DeleteTodo;
}

SelectTodo va récupérer le contenu du payload, et UpdateTodo va changer la todo qui match avec l'id du payload :

/store/reducers/todo-list.reducer.ts

import { TodoListModule } from '../actions/todo-list.action';
import { TodoListState  } from '../../models/todo';
import { todosMock } from '../../mocks/todo-list';

const initialState: TodoListState = {
    // [...]
    selectTodo: undefined
};

export function todosReducer(
// [...]

    case TodoListModule.ActionTypes.SELECT_TODO:
        return {
            ...state,
            selectTodo: action.payload
        };

    case TodoListModule.ActionTypes.UPDATE_TODO:
        return {
            ...state,
            data: state.data
                .map(todo => action.payload.id === todo.id ? action.payload : todo)
            })
        };


// [...]

Une fonction sera rattachée à l'événement au clique d'une todo. Celle-ci redirigera l'utilisateur vers la page /select-todo tout en modifiant le state selectTodo :

all-todos.ts

// [...]
import { Router } from '@angular/router';

@Component({
  selector: 'app-all-todos',
  styleUrls: ['./all-todos.component.scss'],
  template: `
    <!-- reste -->
    <ul>
      <li *ngFor="let todo of todos$ | async; let i = index" >
        <!-- reste -->
        <button (click)="selectTodo(todo)">Modifier</button>
      </li>
    </ul>
  `
})
export class AllTodosComponent implements OnInit {
  // [...]
  constructor(
    // [...]
    private router: Router) {
    // [...]
  }

  // [...]
  selectTodo(todo) {
    this.store.dispatch(new TodoListModule.SelectTodo(todo));
    this.router.navigate(['/todo-list/select-todo']);
  }
  // [...]
}

Reste la fonctionnalité de UpdateTodo qui sera dans le SelectTodoComponent :

modules/todo-list/components/select-todo/select-todo.component.ts

import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { tap } from 'rxjs/operators';
import { Component, Inject, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { AppState } from '@StoreConfig';
import { selectTodoSelected$ } from '@Selectors/todo-list.selector';
import { TodoListModule } from '@Actions/todo-list.action';
import { TodoListState, Todo } from '@Models/todo';
import { Router } from '@angular/router';

@Component({
  selector: 'app-select-todo',
  styleUrls: ['./select-todo.component.scss'],
  template: `
      <h1>Mettre à jour la todo</h1>
      <form *ngIf="selectTodo$ | async; else NoElement"
      [formGroup]="updateTodoForm"
      (ngSubmit)="updateTodo(updateTodoForm.value)">
          <label>Titre :</label>
          <input type="text" formControlName="title" placeholder="Title"/>
          <label>Est-elle terminé ? :</label>
          <input type="checkbox" formControlName="completed"/>
          <button>Mettre à jour</button>
    </form>
    <ng-template #NoElement>Pas de todo séléctionner<ng-template>
  `
})
export class SelectTodoComponent implements OnInit {

    public updateTodoForm: FormGroup;
    public selectTodo$: Observable<Todo>;
    public selectTodo: Todo;

  constructor(
    private store: Store<AppState>,
    private router: Router,
    @Inject(FormBuilder) fb: FormBuilder
  ) {
  this.selectTodo$ = store
  .pipe(
    select(selectTodoSelected$),
    tap(selectTodos => {
      this.selectTodo = selectTodos;
    })
  );

  this.selectTodo$.subscribe();

    this.updateTodoForm = fb.group({
      title: ['', Validators.required],
      completed: [false, Validators]
    });
  }
  ngOnInit() {
    if (this.selectTodo) {
      this.updateTodoForm.patchValue({
        title: this.selectTodo.title,
        completed: this.selectTodo.completed
      });
    }
  }

  updateTodo(formValue) {
    const payload = Object.assign(this.selectTodo, formValue);
    this.store.dispatch(new TodoListModule.UpdateTodo(payload));
    return this.router.navigate(['/todo-list/all-todos']);
  }

}

Vous pouvez maintenant sélectionner et mettre à jour une todo.

PreviousUn peu de refactoNextAPI

Last updated 5 years ago

Was this helpful?

Suite >>