Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Angular Architectures with NgRx Stores & Effects

Angular Architectures with NgRx Stores & Effects

Angular offers many possibilities in the frontend, but also some challenges. If an application grows, sooner or later you have to deal with the issue of the state of the application. But what do "stateful" and "stateless" mean anyway? What are "Container Components" and "Presentation Components"? And how do I get a clean grip on the state of my application in the frontend? Tools like ngrx can help us to design our application cleanly and especially for large applications they help to keep track of the state. In this talk by Fabian Gosebrink, you will learn how these tools can be used and help you to manage even large applications with Angular.

Fabian Gosebrink

April 26, 2022
Tweet

More Decks by Fabian Gosebrink

Other Decks in Technology

Transcript

  1. export class ContentComponent implements OnInit { items: Todo[]; doneItems: Todo[];

    constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe(data => this.items = data); this.service.detDoneItems() .subscribe(data => this.doneItems = data); } addTodo(item: string) { // ... } markAsDone(item: Todo) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
  2. export class ContentComponent implements OnInit { items: Todo[]; doneItems: Todo[];

    constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe(data => this.items = data); this.service.detDoneItems() .subscribe(data => this.doneItems = data); } addTodo(item: string) { // ... } markAsDone(item: Todo) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 constructor(private service: Service) {} export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22
  3. export class ContentComponent implements OnInit { items: Todo[]; doneItems: Todo[];

    constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe(data => this.items = data); this.service.detDoneItems() .subscribe(data => this.doneItems = data); } addTodo(item: string) { // ... } markAsDone(item: Todo) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 constructor(private service: Service) {} export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.getData() .subscribe(data => this.items = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 8 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22
  4. export class ContentComponent implements OnInit { items: Todo[]; doneItems: Todo[];

    constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe(data => this.items = data); this.service.detDoneItems() .subscribe(data => this.doneItems = data); } addTodo(item: string) { // ... } markAsDone(item: Todo) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 constructor(private service: Service) {} export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.getData() .subscribe(data => this.items = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 8 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.detDoneItems() .subscribe(data => this.doneItems = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 11 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22
  5. export class ContentComponent implements OnInit { items: Todo[]; doneItems: Todo[];

    constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe(data => this.items = data); this.service.detDoneItems() .subscribe(data => this.doneItems = data); } addTodo(item: string) { // ... } markAsDone(item: Todo) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 constructor(private service: Service) {} export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.getData() .subscribe(data => this.items = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 8 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.detDoneItems() .subscribe(data => this.doneItems = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 11 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 addTodo(item: string) { // ... } export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 15 16 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22
  6. export class ContentComponent implements OnInit { items: Todo[]; doneItems: Todo[];

    constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe(data => this.items = data); this.service.detDoneItems() .subscribe(data => this.doneItems = data); } addTodo(item: string) { // ... } markAsDone(item: Todo) { // ... } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 constructor(private service: Service) {} export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.getData() .subscribe(data => this.items = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 8 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 this.service.detDoneItems() .subscribe(data => this.doneItems = data); export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 11 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 addTodo(item: string) { // ... } export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 15 16 17 18 markAsDone(item: Todo) { 19 // ... 20 } 21 } 22 markAsDone(item: Todo) { // ... } export class ContentComponent implements OnInit { 1 items: Todo[]; 2 doneItems: Todo[]; 3 4 constructor(private service: Service) {} 5 6 ngOnInit() { 7 this.service.getData() 8 .subscribe(data => this.items = data); 9 10 this.service.detDoneItems() 11 .subscribe(data => this.doneItems = data); 12 } 13 14 addTodo(item: string) { 15 // ... 16 } 17 18 19 20 21 } 22
  7. <div> <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <app-todo-list [items]="items" [doneItems]="doneItems" (markAsDone)="markAsDone($event)" ></app-todo-list> </div>

    1 2 3 4 5 6 7 8 9 10 11 <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <div> 1 2 3 4 5 <app-todo-list 6 [items]="items" 7 [doneItems]="doneItems" 8 (markAsDone)="markAsDone($event)" 9 ></app-todo-list> 10 </div> 11
  8. <div> <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <app-todo-list [items]="items" [doneItems]="doneItems" (markAsDone)="markAsDone($event)" ></app-todo-list> </div>

    1 2 3 4 5 6 7 8 9 10 11 <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <div> 1 2 3 4 5 <app-todo-list 6 [items]="items" 7 [doneItems]="doneItems" 8 (markAsDone)="markAsDone($event)" 9 ></app-todo-list> 10 </div> 11 <app-todo-list [items]="items" [doneItems]="doneItems" (markAsDone)="markAsDone($event)" ></app-todo-list> <div> 1 <app-todo-form 2 (todoAdded)="addTodo($event)"> 3 </app-todo-form> 4 5 6 7 8 9 10 </div> 11
  9. export class TodoListComponent { @Input() items: Todo[] = []; @Input()

    doneItems: Todo[] = []; @Output() markAsDone = new EventEmitter(); moveToDone(item: Todo) { this.markAsDone.emit(item); } } 1 2 3 4 5 6 7 8 9 10
  10. export class TodoListComponent { @Input() items: Todo[] = []; @Input()

    doneItems: Todo[] = []; @Output() markAsDone = new EventEmitter(); moveToDone(item: Todo) { this.markAsDone.emit(item); } } 1 2 3 4 5 6 7 8 9 10 @Input() items: Todo[] = []; @Input() doneItems: Todo[] = []; export class TodoListComponent { 1 2 3 4 @Output() markAsDone = new EventEmitter(); 5 6 moveToDone(item: Todo) { 7 this.markAsDone.emit(item); 8 } 9 } 10
  11. export class TodoListComponent { @Input() items: Todo[] = []; @Input()

    doneItems: Todo[] = []; @Output() markAsDone = new EventEmitter(); moveToDone(item: Todo) { this.markAsDone.emit(item); } } 1 2 3 4 5 6 7 8 9 10 @Input() items: Todo[] = []; @Input() doneItems: Todo[] = []; export class TodoListComponent { 1 2 3 4 @Output() markAsDone = new EventEmitter(); 5 6 moveToDone(item: Todo) { 7 this.markAsDone.emit(item); 8 } 9 } 10 @Output() markAsDone = new EventEmitter(); this.markAsDone.emit(item); export class TodoListComponent { 1 @Input() items: Todo[] = []; 2 @Input() doneItems: Todo[] = []; 3 4 5 6 moveToDone(item: Todo) { 7 8 } 9 } 10
  12. export class TodoListComponent { @Input() items: Todo[] = []; @Input()

    doneItems: Todo[] = []; @Output() markAsDone = new EventEmitter(); moveToDone(item: Todo) { this.markAsDone.emit(item); } } 1 2 3 4 5 6 7 8 9 10 @Input() items: Todo[] = []; @Input() doneItems: Todo[] = []; export class TodoListComponent { 1 2 3 4 @Output() markAsDone = new EventEmitter(); 5 6 moveToDone(item: Todo) { 7 this.markAsDone.emit(item); 8 } 9 } 10 @Output() markAsDone = new EventEmitter(); this.markAsDone.emit(item); export class TodoListComponent { 1 @Input() items: Todo[] = []; 2 @Input() doneItems: Todo[] = []; 3 4 5 6 moveToDone(item: Todo) { 7 8 } 9 } 10 export class TodoListComponent { @Input() items: Todo[] = []; @Input() doneItems: Todo[] = []; @Output() markAsDone = new EventEmitter(); moveToDone(item: Todo) { this.markAsDone.emit(item); } } 1 2 3 4 5 6 7 8 9 10
  13. S I N G L E S O U R

    C E O F T R U T H
  14. S T O R E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent { constructor(private store: Store) {} } 1 2 3 4 5 6 7 8 9
  15. S T O R E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent { constructor(private store: Store) {} } 1 2 3 4 5 6 7 8 9 import { Store } from '@ngrx/store'; constructor(private store: Store) {} import { Component, OnInit } from '@angular/core'; 1 2 3 @Component({ /*...*/ }) 4 export class ContentComponent { 5 6 7 8 } 9
  16. S T A T E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  17. S T A T E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 constructor(private store: Store) {} import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15
  18. S T A T E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 constructor(private store: Store) {} import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.items$ = this.store.select(state => state.items); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15
  19. S T A T E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 constructor(private store: Store) {} import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.items$ = this.store.select(state => state.items); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.loading$ = this.store.select(state => state.loading); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 13 } 14 } 15
  20. S T A T E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 constructor(private store: Store) {} import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.items$ = this.store.select(state => state.items); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.loading$ = this.store.select(state => state.loading); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 13 } 14 } 15 items$: Observable<Todo[]>; loading$: Observable<boolean>; import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15
  21. S T A T E import { Component, OnInit }

    from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 constructor(private store: Store) {} import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.items$ = this.store.select(state => state.items); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 this.loading$ = this.store.select(state => state.loading); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 items$: Observable<Todo[]>; 6 loading$: Observable<boolean>; 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 13 } 14 } 15 items$: Observable<Todo[]>; loading$: Observable<boolean>; import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 7 8 constructor(private store: Store) {} 9 10 ngOnInit() { 11 this.items$ = this.store.select(state => state.items); 12 this.loading$ = this.store.select(state => state.loading); 13 } 14 } 15 import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { items$: Observable<Todo[]>; loading$: Observable<boolean>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state.items); this.loading$ = this.store.select(state => state.loading); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  22. S T A T E <div> <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <app-todo-list

    [items]="items$ | async" ... (markAsDone)="markAsDone($event)" ></app-todo-list> </div> 1 2 3 4 5 6 7 8 9 10 11
  23. S T A T E <div> <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <app-todo-list

    [items]="items$ | async" ... (markAsDone)="markAsDone($event)" ></app-todo-list> </div> 1 2 3 4 5 6 7 8 9 10 11 [items]="items$ | async" <div> 1 <app-todo-form 2 (todoAdded)="addTodo($event)"> 3 </app-todo-form> 4 5 <app-todo-list 6 7 ... 8 (markAsDone)="markAsDone($event)" 9 ></app-todo-list> 10 </div> 11
  24. A C T I O N S import { createAction

    } from '@ngrx/store'; createAction(...); 1 2 3
  25. A C T I O N S import { createAction

    } from '@ngrx/store'; createAction('[Todo] Load Todos'); 1 2 3
  26. A C T I O N S import { createAction

    } from '@ngrx/store'; export const loadAllTodos = createAction('[Todo] Load Todos'); 1 2 3
  27. A C T I O N S import { createAction

    } from '@ngrx/store'; export const loadAllTodos = createAction('[Todo] Load Todos'); export const loadAllTodosFinished = createAction( '[Todo] Load Todos Finished' ); 1 2 3 4 5 6 7
  28. A C T I O N S import { createAction,

    props } from '@ngrx/store'; export const loadAllTodos = createAction('[Todo] Load Todos'); export const loadAllTodosFinished = createAction( '[Todo] Load Todos Finished', props<{ payload: Todo[] }>() ); 1 2 3 4 5 6 7 8
  29. A C T I O N S import { createAction,

    props } from '@ngrx/store'; export const loadAllTodos = createAction('[Todo] Load Todos'); export const loadAllTodosFinished = createAction( '[Todo] Load Todos Finished', props<{ payload: Todo[] }>() ); export const addTodo = createAction( '[Todo] Add Todo', props<{ payload: string }>() ); export const addTodoFinished = createAction( '[Todo] Add Todo Finished', props<{ payload: Todo }>() ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  30. A C T I O N S import { Component,

    OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import * as todoActions from '../../store/todo.actions'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state...); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  31. A C T I O N S import { Component,

    OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import * as todoActions from '../../store/todo.actions'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state...); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import * as todoActions from '../../store/todo.actions'; import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 4 @Component({ /*...*/ }) 5 export class ContentComponent implements OnInit { 6 7 constructor(private store: Store) {} 8 9 ngOnInit() { 10 this.items$ = this.store.select(state => state...); 11 12 this.store.dispatch(todoActions.loadAllTodos()); 13 } 14 } 15
  32. A C T I O N S import { Component,

    OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import * as todoActions from '../../store/todo.actions'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.select(state => state...); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import * as todoActions from '../../store/todo.actions'; import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 4 @Component({ /*...*/ }) 5 export class ContentComponent implements OnInit { 6 7 constructor(private store: Store) {} 8 9 ngOnInit() { 10 this.items$ = this.store.select(state => state...); 11 12 this.store.dispatch(todoActions.loadAllTodos()); 13 } 14 } 15 this.store.dispatch(todoActions.loadAllTodos()); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 import * as todoActions from '../../store/todo.actions'; 3 4 @Component({ /*...*/ }) 5 export class ContentComponent implements OnInit { 6 7 constructor(private store: Store) {} 8 9 ngOnInit() { 10 this.items$ = this.store.select(state => state...); 11 12 13 } 14 } 15
  33. R E D U C E R import { Action,

    createReducer, on } from '@ngrx/store'; import * as todoActions from './todo.actions'; export interface ReducerTodoState { items: Todo[]; selectedItem: Todo; loading: boolean; } export const initialState: ReducerTodoState = { items: [], selectedItem: null, loading: false }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  34. R E D U C E R import { Action,

    createReducer, on } from '@ngrx/store'; import * as todoActions from './todo.actions'; export interface ReducerTodoState { ... } export const initialState: ReducerTodoState = { ... }; const todoReducer = createReducer( initialState, on(todoActions.loadAllTodos, (state) => ({ ...state, loading: true, }) ), ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  35. R E D U C E R import { Action,

    createReducer, on } from '@ngrx/store'; import * as todoActions from './todo.actions'; export interface ReducerTodoState { ... } export const initialState: ReducerTodoState = { ... }; const todoReducer = createReducer( initialState, on(todoActions.loadAllTodos, (state) => ({ ...state, loading: true, }) ), ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const initialState: ReducerTodoState = { ... }; const todoReducer = createReducer( initialState, import { Action, createReducer, on } from '@ngrx/store'; 1 import * as todoActions from './todo.actions'; 2 3 export interface ReducerTodoState { ... } 4 5 6 7 8 9 on(todoActions.loadAllTodos, 10 (state) => ({ 11 ...state, 12 loading: true, 13 }) 14 ), 15 ); 16
  36. R E D U C E R import { Action,

    createReducer, on } from '@ngrx/store'; import * as todoActions from './todo.actions'; export interface ReducerTodoState { ... } export const initialState: ReducerTodoState = { ... }; const todoReducer = createReducer( initialState, on(todoActions.loadAllTodos, (state) => ({ ...state, loading: true, }) ), ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const initialState: ReducerTodoState = { ... }; const todoReducer = createReducer( initialState, import { Action, createReducer, on } from '@ngrx/store'; 1 import * as todoActions from './todo.actions'; 2 3 export interface ReducerTodoState { ... } 4 5 6 7 8 9 on(todoActions.loadAllTodos, 10 (state) => ({ 11 ...state, 12 loading: true, 13 }) 14 ), 15 ); 16 on(todoActions.loadAllTodos, (state) => ({ ...state, loading: true, }) ), import { Action, createReducer, on } from '@ngrx/store'; 1 import * as todoActions from './todo.actions'; 2 3 export interface ReducerTodoState { ... } 4 5 export const initialState: ReducerTodoState = { ... }; 6 7 const todoReducer = createReducer( 8 initialState, 9 10 11 12 13 14 15 ); 16
  37. E F F E C T S @Injectable() export class

    TodoEffects { } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  38. E F F E C T S @Injectable() export class

    TodoEffects { loadTodos$ = createEffect(() => ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  39. E F F E C T S @Injectable() export class

    TodoEffects { loadTodos$ = createEffect(() => this.actions$.pipe( ) ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  40. E F F E C T S @Injectable() export class

    TodoEffects { loadTodos$ = createEffect(() => this.actions$.pipe( ofType(todoActions.loadAllTodos), switchMap(() => ) ) ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  41. E F F E C T S @Injectable() export class

    TodoEffects { loadTodos$ = createEffect(() => this.actions$.pipe( ofType(todoActions.loadAllTodos), switchMap(() => this.todoService .getItems() ) ) ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  42. E F F E C T S @Injectable() export class

    TodoEffects { loadTodos$ = createEffect(() => this.actions$.pipe( ofType(todoActions.loadAllTodos), switchMap(() => this.todoService .getItems() .pipe( map((todos) => todoActions.loadAllTodosFinished({ payload: todos })) ) ) ) ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  43. E F F E C T S @Injectable() export class

    TodoEffects { loadTodos$ = createEffect(() => this.actions$.pipe( ofType(todoActions.loadAllTodos), switchMap(() => this.todoService .getItems() .pipe( map((todos) => todoActions.loadAllTodosFinished({ payload: todos })) ) ) ) ); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 todoActions.loadAllTodosFinished({ payload: todos })) @Injectable() 1 export class TodoEffects { 2 loadTodos$ = createEffect(() => 3 this.actions$.pipe( 4 ofType(todoActions.loadAllTodos), 5 switchMap(() => 6 this.todoService 7 .getItems() 8 .pipe( 9 map((todos) => 10 11 ) 12 ) 13 ) 14 ); 15 } 16
  44. import { Action, createReducer, on } from '@ngrx/store'; import *

    as todoActions from './todo.actions'; const todoReducer = createReducer( initialState, on(todoActions.loadAllTodos, (state) => ({ ...state, loading: true, }) ), on(todoActions.loadAllTodosFinished, (state, { payload }) => { return { ...state, loading: false, items: [...payload], }; }), ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
  45. import { Action, createReducer, on } from '@ngrx/store'; import *

    as todoActions from './todo.actions'; const todoReducer = createReducer( initialState, on(todoActions.loadAllTodos, (state) => ({ ...state, loading: true, }) ), on(todoActions.loadAllTodosFinished, (state, { payload }) => { return { ...state, loading: false, items: [...payload], }; }), ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 on(todoActions.loadAllTodosFinished, (state, { payload }) => { return { ...state, loading: false, items: [...payload], }; }), import { Action, createReducer, on } from '@ngrx/store'; 1 import * as todoActions from './todo.actions'; 2 3 const todoReducer = createReducer( 4 initialState, 5 on(todoActions.loadAllTodos, 6 (state) => ({ 7 ...state, 8 loading: true, 9 }) 10 ), 11 12 13 14 15 16 17 18 19 ); 20
  46. @Component({/* ... */ }) export class ContentComponent implements OnInit {

    items$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(/*...*/)); this.store.dispatch(todoActions.loadAllTodos()); } addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  47. @Component({/* ... */ }) export class ContentComponent implements OnInit {

    items$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(/*...*/)); this.store.dispatch(todoActions.loadAllTodos()); } addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 constructor(private store: Store) {} @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19
  48. @Component({/* ... */ }) export class ContentComponent implements OnInit {

    items$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(/*...*/)); this.store.dispatch(todoActions.loadAllTodos()); } addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 constructor(private store: Store) {} @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.items$ = this.store.pipe(select(/*...*/)); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19
  49. @Component({/* ... */ }) export class ContentComponent implements OnInit {

    items$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(/*...*/)); this.store.dispatch(todoActions.loadAllTodos()); } addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 constructor(private store: Store) {} @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.items$ = this.store.pipe(select(/*...*/)); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.store.dispatch(todoActions.loadAllTodos()); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19
  50. @Component({/* ... */ }) export class ContentComponent implements OnInit {

    items$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(/*...*/)); this.store.dispatch(todoActions.loadAllTodos()); } addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 constructor(private store: Store) {} @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.items$ = this.store.pipe(select(/*...*/)); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.store.dispatch(todoActions.loadAllTodos()); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 12 13 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19
  51. @Component({/* ... */ }) export class ContentComponent implements OnInit {

    items$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(/*...*/)); this.store.dispatch(todoActions.loadAllTodos()); } addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 constructor(private store: Store) {} @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.items$ = this.store.pipe(select(/*...*/)); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 this.store.dispatch(todoActions.loadAllTodos()); @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 addTodo(item: string) { this.store.dispatch(todoActions.addTodo({ payload: item })); } @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 12 13 14 15 markAsDone(item: Todo) { 16 this.store.dispatch(todoActions.setAsDone({ payload: item })); 17 } 18 } 19 markAsDone(item: Todo) { this.store.dispatch(todoActions.setAsDone({ payload: item })); } @Component({/* ... */ }) 1 export class ContentComponent implements OnInit { 2 items$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(/*...*/)); 8 this.store.dispatch(todoActions.loadAllTodos()); 9 } 10 11 addTodo(item: string) { 12 this.store.dispatch(todoActions.addTodo({ payload: item })); 13 } 14 15 16 17 18 } 19
  52. <h1>Todo App</h1> <app-todo-form (todoAdded)="addTodo($event)"> </app-todo-form> <app-todo-list [items]="items$ | async" (markAsDone)="markAsDone($event)"

    ></app-todo-list> 1 2 3 4 5 6 7 8 9 [items]="items$ | async" <h1>Todo App</h1> 1 2 <app-todo-form (todoAdded)="addTodo($event)"> 3 </app-todo-form> 4 5 <app-todo-list 6 7 (markAsDone)="markAsDone($event)" 8 ></app-todo-list> 9
  53. import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo",

    todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 StoreModule.forFeature("todo", todoReducer) import { StoreModule } from '@ngrx/store'; 1 2 @NgModule({ 3 imports: [ 4 5 ] 6 }) 7 export class TodoModule {} 8
  54. import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo",

    todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 { todo: { // ... } } 1 2 3 4 5
  55. import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo",

    todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 { todo: { // ... } } 1 2 3 4 5
  56. import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo",

    todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 { todo: { items: [], selectedItem: null, loading: false } } 1 2 3 4 5 6 7
  57. import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo",

    todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 { todo: { items: [], selectedItem: null, loading: false } } 1 2 3 4 5 6 7
  58. import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo",

    todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 import { StoreModule } from '@ngrx/store'; @NgModule({ imports: [ StoreModule.forFeature("todo", todoReducer) ] }) export class TodoModule {} 1 2 3 4 5 6 7 8 { todo: { items: [], selectedItem: null, loading: false } } 1 2 3 4 5 6 7
  59. SELECTORS import { Component, OnInit } from '@angular/core'; import {

    Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { const items$ = this.store.pipe( select((state) => state ) ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  60. SELECTORS import { Component, OnInit } from '@angular/core'; import {

    Store } from '@ngrx/store'; @Component({ /*...*/ }) export class ContentComponent implements OnInit { constructor(private store: Store) {} ngOnInit() { const items$ = this.store.pipe( select((state) => state ) ); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const items$ = this.store.pipe( select((state) => state ) ); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 constructor(private store: Store) {} 7 8 ngOnInit() { 9 10 11 12 13 14 15 16 } 17 } 18
  61. SELECTORS const items$ = this.store.pipe( select((state) => state.todo )) );

    import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 constructor(private store: Store) {} 7 8 ngOnInit() { 9 10 11 12 13 14 15 16 } 17 } 18
  62. SELECTORS const items$ = this.store.pipe( select((state) => state.todo.items )) );

    import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 constructor(private store: Store) {} 7 8 ngOnInit() { 9 10 11 12 13 14 15 16 } 17 } 18
  63. SELECTORS const items$ = this.store.pipe( select((state) => state.todo.items.filter((x) => !x.done))

    ); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 constructor(private store: Store) {} 7 8 ngOnInit() { 9 10 11 12 13 14 15 16 } 17 } 18
  64. SELECTORS const doneItems$ = this.store.pipe( select((state) => state.todo.items.filter((x) => x.done))

    ); import { Component, OnInit } from '@angular/core'; 1 import { Store } from '@ngrx/store'; 2 3 @Component({ /*...*/ }) 4 export class ContentComponent implements OnInit { 5 6 constructor(private store: Store) {} 7 8 ngOnInit() { 9 const items$ = this.store.pipe( 10 select((state) => state.todo.items.filter((x) => !x.done)) 11 ); 12 13 14 15 16 } 17 } 18
  65. SELECTORS export const getTodoState = createFeatureSelector<TodoState>("todo"); export const getAllUndoneItems =

    createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getSelectedItem = createSelector( getTodoState, (state: TodoState) => state.selectedItem ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  66. SELECTORS export const getTodoState = createFeatureSelector<TodoState>("todo"); export const getAllUndoneItems =

    createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getSelectedItem = createSelector( getTodoState, (state: TodoState) => state.selectedItem ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16
  67. SELECTORS export const getTodoState = createFeatureSelector<TodoState>("todo"); export const getAllUndoneItems =

    createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getSelectedItem = createSelector( getTodoState, (state: TodoState) => state.selectedItem ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16 export const getAllUndoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 3 4 5 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16
  68. SELECTORS export const getTodoState = createFeatureSelector<TodoState>("todo"); export const getAllUndoneItems =

    createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getSelectedItem = createSelector( getTodoState, (state: TodoState) => state.selectedItem ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16 export const getAllUndoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 3 4 5 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16 export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 8 9 10 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16
  69. SELECTORS export const getTodoState = createFeatureSelector<TodoState>("todo"); export const getAllUndoneItems =

    createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getSelectedItem = createSelector( getTodoState, (state: TodoState) => state.selectedItem ); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16 export const getAllUndoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => !x.done) ); export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 3 4 5 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16 export const getAllDoneItems = createSelector( getTodoState, (state: TodoState) => state.items.filter((x) => x.done) ); export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 8 9 10 11 12 export const getSelectedItem = createSelector( 13 getTodoState, 14 (state: TodoState) => state.selectedItem 15 ); 16 export const getSelectedItem = createSelector( getTodoState, (state: TodoState) => state.selectedItem ); export const getTodoState = createFeatureSelector<TodoState>("todo"); 1 2 export const getAllUndoneItems = createSelector( 3 getTodoState, 4 (state: TodoState) => state.items.filter((x) => !x.done) 5 ); 6 7 export const getAllDoneItems = createSelector( 8 getTodoState, 9 (state: TodoState) => state.items.filter((x) => x.done) 10 ); 11 12 13 14 15 16
  70. SELECTORS export class ContentComponent implements OnInit { items: Todo[]; doneItems:

    Todo[]; constructor(private service: Service) {} ngOnInit() { this.service.getData() .subscribe((data) => { this.items = data }); this.service.detDoneItems() .subscribe((data) => { this.items = data }); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  71. SELECTORS export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$:

    Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13
  72. SELECTORS export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$:

    Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 constructor(private store: Store) {} export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13
  73. SELECTORS export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$:

    Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 constructor(private store: Store) {} export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.items$ = this.store.pipe(select(getAllUndoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13
  74. SELECTORS export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$:

    Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 constructor(private store: Store) {} export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.items$ = this.store.pipe(select(getAllUndoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13
  75. SELECTORS export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$:

    Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 constructor(private store: Store) {} export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.items$ = this.store.pipe(select(getAllUndoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.store.dispatch(todoActions.loadAllTodos()); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 11 } 12 } 13
  76. SELECTORS export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$:

    Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 constructor(private store: Store) {} export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.items$ = this.store.pipe(select(getAllUndoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 9 10 this.store.dispatch(todoActions.loadAllTodos()); 11 } 12 } 13 this.store.dispatch(todoActions.loadAllTodos()); export class ContentComponent implements OnInit { 1 items$: Observable<Todo[]>; 2 doneItems$: Observable<Todo[]>; 3 4 constructor(private store: Store) {} 5 6 ngOnInit() { 7 this.items$ = this.store.pipe(select(getAllUndoneItems)); 8 this.doneItems$ = this.store.pipe(select(getAllDoneItems)); 9 10 11 } 12 } 13 export class ContentComponent implements OnInit { items$: Observable<Todo[]>; doneItems$: Observable<Todo[]>; constructor(private store: Store) {} ngOnInit() { this.items$ = this.store.pipe(select(getAllUndoneItems)); this.doneItems$ = this.store.pipe(select(getAllDoneItems)); this.store.dispatch(todoActions.loadAllTodos()); } } 1 2 3 4 5 6 7 8 9 10 11 12 13
  77. @NGRX/DATA import { EntityMetadataMap } from '@ngrx/data'; const entityMetadata: EntityMetadataMap

    = { Hero: {}, }; export const entityConfig = { entityMetadata }; 1 2 3 4 5 6 7 8 9
  78. @NGRX/DATA import ... import { EntityDataModule } from '@ngrx/data'; import

    { entityConfig } from './entity-metadata'; @NgModule({ imports: [ HttpClientModule, StoreModule.forRoot({}), EffectsModule.forRoot([]), EntityDataModule.forRoot(entityConfig) ] }) export class AppModule {} 1 2 3 4 5 6 7 8 9 10 11 12 13
  79. @NGRX/DATA import { Injectable } from '@angular/core'; import { EntityCollectionServiceBase,

    EntityCollectionServiceElementsFactory } from '@ngrx/data'; import { Hero } from '../core'; @Injectable({ providedIn: 'root' }) export class HeroService extends EntityCollectionServiceBase<Hero> { constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) { super('Hero', serviceElementsFactory); } } 1 2 3 4 5 6 7 8 9 10 11 12 13
  80. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
  81. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 5 6 7 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23
  82. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 5 6 7 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 loading$: Observable<boolean>; heroes$: Observable<Hero[]>; export class HeroesComponent implements OnInit { 1 2 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23
  83. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 5 6 7 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 loading$: Observable<boolean>; heroes$: Observable<Hero[]>; export class HeroesComponent implements OnInit { 1 2 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 add(hero: Hero) { this.heroService.add(hero); } 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 14 15 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 this.heroService.getAll(); 23 } 24 25 update(hero: Hero) { 26
  84. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 5 6 7 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 loading$: Observable<boolean>; heroes$: Observable<Hero[]>; export class HeroesComponent implements OnInit { 1 2 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 add(hero: Hero) { this.heroService.add(hero); } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 14 15 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 delete(hero: Hero) { this.heroService.delete(hero.id); } this.loading$ heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 18 19 20 21 getHeroes() { 22 this.heroService.getAll(); 23 } 24 25 update(hero: Hero) { 26 this.heroService.update(hero); 27 } 28 } 29
  85. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 5 6 7 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 loading$: Observable<boolean>; heroes$: Observable<Hero[]>; export class HeroesComponent implements OnInit { 1 2 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 add(hero: Hero) { this.heroService.add(hero); } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 14 15 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 delete(hero: Hero) { this.heroService.delete(hero.id); } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 18 19 20 21 getHeroes() { 22 hi h i ll 23 getHeroes() { this.heroService.getAll(); } this.loading$ heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 22 23 24 25 update(hero: Hero) { 26 this.heroService.update(hero); 27 } 28 } 29
  86. @NGRX/DATA export class HeroesComponent implements OnInit { loading$: Observable<boolean>; heroes$:

    Observable<Hero[]>; constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } ngOnInit() { this.getHeroes(); } add(hero: Hero) { this.heroService.add(hero); } delete(hero: Hero) { this.heroService.delete(hero.id); } getHeroes() { hi h i ll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 constructor(private heroService: HeroService) { this.heroes$ = heroService.entities$; this.loading$ = heroService.loading$; } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 5 6 7 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 loading$: Observable<boolean>; heroes$: Observable<Hero[]>; export class HeroesComponent implements OnInit { 1 2 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 add(hero: Hero) { this.heroService.add(hero); } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 14 15 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 hi h i ll 23 delete(hero: Hero) { this.heroService.delete(hero.id); } export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 18 19 20 21 getHeroes() { 22 hi h i ll 23 getHeroes() { hi h i ll export class HeroesComponent implements OnInit { 1 loading$: Observable<boolean>; 2 heroes$: Observable<Hero[]>; 3 4 constructor(private heroService: HeroService) { 5 this.heroes$ = heroService.entities$; 6 this.loading$ = heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 22 23 update(hero: Hero) { this.heroService.update(hero); } this.loading$ heroService.loading$; 7 } 8 9 ngOnInit() { 10 this.getHeroes(); 11 } 12 13 add(hero: Hero) { 14 this.heroService.add(hero); 15 } 16 17 delete(hero: Hero) { 18 this.heroService.delete(hero.id); 19 } 20 21 getHeroes() { 22 this.heroService.getAll(); 23 } 24 25 26 27 28 } 29