Skip to content

giemic8/angular-ngrx

Repository files navigation

Development server

To start a local development server, run:

ng serve

Once the server is running, open your browser and navigate to http://localhost:4200/. The application will automatically reload whenever you modify any of the source files.

Übung 1 Erstelle eine Todo-App mit NgRx Store

Ziel: Zwei Angular Standalone Components mit NgRx bauen.

  • TodoListComponent: nutzt nur NgRx Store. Keine HTTP-API, kein CRUD-Service, keine Effects.
  • RandomUserComponent: nutzt NgRx Store + Effects + HttpClient gegen https://randomuser.me/api/.

1. Dependencies

npm install @ngrx/store @ngrx/effects @ngrx/store-devtools

@ngrx/store haelt State. @ngrx/effects kapselt Side Effects wie HTTP. @ngrx/store-devtools zeigt Actions und State im Redux DevTools Browser-Plugin.

2. Store in Angular registrieren

Datei: src/app/app.config.ts

provideHttpClient(),
provideStore({
  [todosFeatureKey]: todosReducer,
  [randomUsersFeatureKey]: randomUsersReducer,
}),
provideEffects([RandomUserEffects]),
provideStoreDevtools({
  maxAge: 25,
  logOnly: !isDevMode(),
}),

Damit kennt Angular beide Feature States. provideHttpClient() wird nur fuer RandomUser gebraucht.

3. Todo-Liste ohne Effects

Dateien:

  • src/app/state/todos/todo.model.ts
  • src/app/state/todos/todo.actions.ts
  • src/app/state/todos/todo.reducer.ts
  • src/app/state/todos/todo.selectors.ts
  • src/app/todo-list/todo-list.component.ts

Flow:

Component -> dispatch(Action) -> Reducer -> neuer State -> Selector -> Template

Actions:

export const todoActions = createActionGroup({
  source: 'Todo List',
  events: {
    'Add Todo': props<{ title: string }>(),
    'Toggle Todo': props<{ id: string }>(),
    'Remove Todo': props<{ id: string }>(),
    'Clear Completed': emptyProps(),
  },
});

Reducer:

on(todoActions.toggleTodo, (state, { id }) => ({
  ...state,
  items: state.items.map((todo) =>
    todo.id === id ? { ...todo, completed: !todo.completed } : todo,
  ),
}))

Wichtig: Reducer mutiert state.items nicht. Er gibt neues Array und neue Todo-Objekte zurueck.

Component:

protected readonly todos$ = this.store.select(selectTodos);

protected toggleTodo(todo: Todo): void {
  this.store.dispatch(todoActions.toggleTodo({ id: todo.id }));
}

Template:

@for (todo of todos$ | async; track todo.id) {
  <li [class.done]="todo.completed">
    <input type="checkbox" [checked]="todo.completed" (change)="toggleTodo(todo)" />
    <span>{{ todo.title }}</span>
  </li>
}

Kein Effect noetig, weil kein externer Seiteneffekt passiert. Alles bleibt synchron im Store.

4. RandomUser mit Effects

Dateien:

  • src/app/state/random-users/random-user.model.ts
  • src/app/state/random-users/random-user.actions.ts
  • src/app/state/random-users/random-user.reducer.ts
  • src/app/state/random-users/random-user.selectors.ts
  • src/app/state/random-users/random-user.service.ts
  • src/app/state/random-users/random-user.effects.ts
  • src/app/random-user/random-user.component.ts

Flow:

Component -> Load Users Action -> Effect -> RandomUserService -> API
API -> Success/Failure Action -> Reducer -> Selector -> Template

Component dispatch:

this.store.dispatch(randomUserActions.loadUsers({ query }));

Effect:

readonly loadUsers$ = createEffect(() =>
  this.actions$.pipe(
    ofType(randomUserActions.loadUsers),
    switchMap(({ query }) =>
      this.randomUserService.loadUsers(query).pipe(
        map((users) => randomUserActions.loadUsersSuccess({ users, query })),
        catchError(() =>
          of(randomUserActions.loadUsersFailure({ error: 'RandomUser API Fehler' })),
        ),
      ),
    ),
  ),
);

Service:

return this.http.get<RandomUserApiResponse>('https://randomuser.me/api/', { params });

Reducer speichert loading, error, query und users. Template zeigt User per users$ | async.

5. DevTools lesen

App starten:

npm start

Dann Browser auf http://localhost:4200/ oeffnen und Redux DevTools nutzen.

Bei Todo siehst du:

  • [Todo List] Add Todo
  • [Todo List] Toggle Todo
  • [Todo List] Remove Todo

Bei RandomUser siehst du:

  • [Random User] Load Users
  • [Random User] Load Users Success
  • [Random User] Load Users Failure

Merksatz: Store beschreibt Zustand. Actions beschreiben Ereignisse. Reducer berechnet neuen Zustand. Effects sprechen mit Welt ausserhalb Angular.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors