Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Angular 2 Design Patterns

13,664 views

Published on

FITC produces events for digital creators in Toronto, Amsterdam, NYC and beyond
Save 10% off any of our events with discount code 'slideshare'
Check out our events at http://fitc.ca
or follow us at https://twitter.com/fitc

Overview

Learning a new framework is hard and it is often tempting to try to reuse the best practices you have learned from another framework. However every framework has it’s own unique way of solving problems and Angular 2 is no exception. So forget everything you know (about JQuery) and start learning Angular 2 the right way.

In this session Rob will add a few challenging features to an Angular 2 app and compare various was of implementing them. You’ll learn how to avoid common pitfalls of the framework and see some novel techniques for solving problems. By the end of the session you will be one step closer to mastering Angular.

Objective

To demonstrate how to approach problem solving the Angular 2 way

Target Audience

Anyone who wants to learn Angular 2 or get better at it

Assumed Audience Knowledge

Some experience building web apps with JavaScript will help but no experience with Angular 2 is required

Five Things Audience Members Will Learn

Common mistakes in Angular 2
Angular 2 best practices
The basics of RxJS
How to solve difficult problems with Angular 2
How best to utilize a component based framework

Published in: Internet

Angular 2 Design Patterns

  1. 1. Angular 2 Design Patterns
  2. 2. Component Communication
  3. 3. What is a component
  4. 4. @Component({ selector: 'myComp', template: ` <div> Content: {{myVar}} </div> ` }) class MyComponent { myVar: string; constructor() { this.myVar = 'hello'; } } Output Input <html> <myComp></myComp> </html> <html> <myComp> <div> Content: hello </div> </myComp> </html>
  5. 5. Parent → Child
  6. 6. @Component({ selector: 'parent', template: ` <div> Parent content <child [param]="myVar"></child> Parent content </div> ` }) class ParentComponent { myVar = 'hello'; } @Component({ selector: 'child', template: '<div>Child: {{param}}</div>' }) class ChildComponent { @Input() param: string; } <html> <parent> <div> Parent content <child> Child hello </child> Parent content </div> </parent> </html> Output Input <html> <parent></parent> </html>
  7. 7. @Input() Demo
  8. 8. Child → Parent
  9. 9. @Component({ selector: 'parent', template: ` <div> <child (childEvent)="handelChildEvent($event)"></child> </div> ` }) class ParentComponent { handelChildEvent(message) { console.log(message); } } @Component({ selector: 'child', template: ` <button (click)="childEvent.emit('clicked')">Click me</button> ` }) class ChildComponent { @Output() childEvent = new EventEmitter(); }
  10. 10. @Output() Demo
  11. 11. Sibling → Sibling
  12. 12. @Component({ selector: 'sibling2', template: ` <button (click)="myService.increment()"> Increment </button>` }) class Sibling2Component { constructor(public myService: MyService) { } } @Component({ selector: 'sibling1', template: `{{myService.counter}}` }) class Sibling1Component { constructor(public myService: MyService) { } } class MyService { counter: number = 0; increment() { this.counter++; } }
  13. 13. Sibling Demo
  14. 14. user.service.ts export class UserService { users: User[] = []; }
  15. 15. user.service.ts export class UserService { private users$ = new BehaviorSubject([]); }
  16. 16. user.service.ts export class UserService { private users$ = new BehaviorSubject([]); addUser(user) { let users = [user, ...this.users$.getValue()]; this.users$.next(users); } }
  17. 17. user.service.ts export class UserService { private users$ = new BehaviorSubject([]); addUser(user) { let users = [user, ...this.users$.getValue()]; this.users$.next(users); } removeUser(user) { let users = this.users$.getValue().filter(u => u !== user); this.users$.next(users); } }
  18. 18. user.service.ts export class UserService { private users$ = new BehaviorSubject([]); addUser(user) { let users = [user, ...this.users$.getValue()]; this.users$.next(users); } removeUser(user) { let users = this.users$.getValue().filter(u => u !== user); this.users$.next(users); } getUsers() { return this.users$.asObservable(); } }
  19. 19. userSearch.component.ts @Component({ selector: 'user-search', template: ` ... <div *ngFor="let user of users | async"> ... </div> ` }) export class UserSearchComponent { users: Observable<User[]>; constructor(public userService: UserService) { this.users = userService.getUsers(); } }
  20. 20. userSearch.component.ts @Component({ selector: 'user-search', template: ` ... First Name: <input #firstName (keyup)="firstNameSearch.next(firstName.value)"> ... ` }) export class UserSearchComponent { firstNameSearch = new BehaviorSubject(''); }
  21. 21. userSearch.component.ts @Component({ selector: 'user-search', template: `...` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(private userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { return users.filter(user => user.firstName.includes(search)); } ); } }
  22. 22. userSearch.component.ts @Component({ selector: 'user-search', template: `...` }) export class UserSearchComponent { users: Observable<User[]>; constructor(private userService: UserService) { ... } removeUser(user: User) { this.userService.removeUser(user); } }
  23. 23. Redux Demo
  24. 24. Takeaways - Everything is a component!!!
  25. 25. Takeaways - Parent → Child - Use an @Input() binding on child component - Use es6 setters or ngOnChanges() to handle changes - When @Input() doesn’t work, inject a @ViewChild()
  26. 26. Takeaways - Child → Parent - Use an @Output() binding on child component - Pass events to parent through an EventEmitter() @Output() doThing = new EventEmitter(); doThing.emit('some event'); - In the parent, get the payload of the event with $event <child (doThing)="handelThing($event)"></child> - If you can’t use an @Output() binding you can inject the parent component directly into the child
  27. 27. Takeaways - Sibling → Sibling - Use a service to communicate between siblings - Try to avoid sharing mutable state - Use observables to push events out from a service to components private state$ = new BehaviorSubject<>({}); doSomething(thing) { this.state$.next(thing); }
  28. 28. Takeaways - ngrx/store (Redux) - ngrx/store library brings redux like approach to Angular 2 - Centralized state - One way data flow
  29. 29. Further Reading Angular Cookbook Component Interaction rxjs/store github.com/ngrx/store egghead.io Building Angular 2 Components egghead.io Step-by-Step Async JavaScript with RxJS
  30. 30. Rob McDiarmid Slides: tinyurl.com/ng2-components @robianmcd

×