Angular 2 Component Communication - Talk by Rob McDiarmid

Component Communication
What is a component
@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>
Parent → Child
@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>
wizardComp
@Input() Demo
Child → Parent
@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();
}
@Output() Demo
Sibling → Sibling
@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++;
}
}
Sibling Demo
user.service.ts
export class UserService {
users: User[] = [];
}
user.service.ts
export class UserService {
private users$ = new BehaviorSubject([]);
}
user.service.ts
export class UserService {
private users$ = new BehaviorSubject([]);
addUser(user) {
let users = [user, ...this.users$.getValue()];
this.users$.next(users);
}
}
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);
}
}
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();
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of filteredUsers">
<input #firstName (keyup)="filterUsers(firstName.value)">
</div>
`
})
export class UserSearchComponent {
filteredUsers: User[];
constructor(public userService: UserService) {
}
filterUsers(search) {
this.filteredUsers = this.userService.users.filter(user =>
user.firstName.includes(search));
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of filteredUsers">
<input #firstName (keyup)="filterUsers(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
constructor(public userService: UserService) {
this.users = userService.getUsers();
}
filterUsers(search) {
this.filteredUsers = this.userService.users.filter(user =>
user.firstName.includes(search));
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of filteredUsers">
<input #firstName (keyup)="filterUsers(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
constructor(public userService: UserService) {
this.users = userService.getUsers();
}
filterUsers(search) {
this.filteredUsers = this.userService.users.filter(user =>
user.firstName.includes(search));
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of users | async">
<input #firstName (keyup)="filterUsers(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
constructor(public userService: UserService) {
this.users = userService.getUsers();
}
filterUsers(search) {
this.filteredUsers = this.userService.users.filter(user =>
user.firstName.includes(search));
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of users | async">
<input #firstName (keyup)="filterUsers(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
constructor(public userService: UserService) {
this.users = userService.getUsers();
}
filterUsers(search) {
this.filteredUsers = this.userService.users.filter(user =>
user.firstName.includes(search));
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of users | async">
<input #firstName (keyup)="firstNameSearch.next(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = userService.getUsers();
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of users | async">
<input #firstName (keyup)="firstNameSearch.next(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = userService.getUsers();
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `
<div *ngFor="let user of users | async">
<input #firstName (keyup)="firstNameSearch.next(firstName.value)">
</div>
`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => {
return users.filter(user => user.firstName.includes(search));
}
);
}
http://rxmarbles.com/#combineLatest
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.users = this.userService.users.filter(u => u !== user);
this.filterUsers(this.firstName.nativeElement.value);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
List Search
User Service
users$ = BehaviorSubject([
'User1',
'User2',
'User3'
])
List Search
User Service
users$ = BehaviorSubject([
'User1',
'User2',
'User3'
])
[
'User1',
'User2',
'User3'
]
List Search
User1 ✖
User2 ✖
User3 ✖
User Service
users$ = BehaviorSubject([
'User1',
'User2',
'User3'
])
[
'User1',
'User2',
'User3'
]
User1
User2
User3
List Search
User1 ✖
User2 ✖
User3 ✖
User1
User2
User3
User Service
users$ = BehaviorSubject([
'User1',
'User2',
'User3'
])
removeUser('User2')
List Search
User1 ✖
User2 ✖
User3 ✖
User1
User2
User3
User Service
users$ = BehaviorSubject([
'User1',
'User3'
])
removeUser('User2')
List Search
User1 ✖
User2 ✖
User3 ✖
User1
User2
User3
User Service
users$ = BehaviorSubject([
'User1',
'User3'
])
[
'User1',
'User3'
]
removeUser('User2')
List Search
User1 ✖
User3 ✖
User1
User3
User Service
users$ = BehaviorSubject([
'User1',
'User3'
])
[
'User1',
'User3'
]
removeUser('User2')
Angular 2 Component Communication - Talk by Rob McDiarmid
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();
}
};
user.service.ts
export const userReducer = (users = [], action) => {
/*
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();
}
*/
};
user.service.ts
export const userReducer = (users = [], action) => {
switch (action.type) {
/*
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();
}
*/
}
};
user.service.ts
export const userReducer = (users = [], action) => {
switch (action.type) {
case 'CREATE_USER':
/*
let users = [user, ...this.users$.getValue()];
this.users$.next(users);
*/
case 'DELETE_USER':
/*
let users = this.users$.getValue().filter(u => u !== user);
this.users$.next(users);
*/
default:
/*
return this.users$.asObservable();
*/
}
};
user.service.ts
export const userReducer = (users = [], action) => {
switch (action.type) {
case 'CREATE_USER':
return [...users, User.fromMockData()];
case 'DELETE_USER':
/*
let users = this.users$.getValue().filter(u => u !== user);
this.users$.next(users);
*/
default:
/*
return this.users$.asObservable();
*/
}
};
user.service.ts
export const userReducer = (users = [], action) => {
switch (action.type) {
case 'CREATE_USER':
return [...users, User.fromMockData()];
case 'DELETE_USER':
return users.filter(user => user.id !== action.payload.id);
default:
/*
return this.users$.asObservable();
*/
}
};
user.service.ts
export const userReducer = (users = [], action) => {
switch (action.type) {
case 'CREATE_USER':
return [...users, User.fromMockData()];
case 'DELETE_USER':
return users.filter(user => user.id !== action.payload.id);
default:
return users;
}
};
app.module.ts
import {userReducer} from "./reducers/userReducer";
@NgModule({
imports: [StoreModule.provideStore({ users: userReducer })
],
declarations: [/*...*/],
providers: [/*...*/],
bootstrap: [/*...*/]
})
class AppModule { }
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public userService: UserService) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public store: Store<AppState>) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public store: Store<AppState>) {
this.users = Observable.combineLatest(
userService.getUsers(),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public store: Store<AppState>) {
this.users = Observable.combineLatest(
store.select(s => s.users),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public store: Store<AppState>) {
this.users = Observable.combineLatest(
store.select(s => s.users),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.userService.removeUser(user);
}
}
userSearch.component.ts
@Component({
selector: 'user-search',
template: `<div *ngFor="let user of users | async"> ... </div>`
})
export class UserSearchComponent {
users: Observable<User[]>;
firstNameSearch = new BehaviorSubject('');
constructor(public store: Store<AppState>) {
this.users = Observable.combineLatest(
store.select(s => s.users),
this.firstNameSearch,
(users, search) => { ... }
);
}
removeUser(user: User) {
this.store.dispatch({type: 'DELETE_USER', payload: {id: user.id}});
}
}
Takeaways
- Everything is a component!!!
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()
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
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);
}
Takeaways - ngrx/store (Redux)
- ngrx/store library brings redux like
approach to Angular 2
- Centralized state
- One way data flow
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
Rob McDiarmid
Slides: tinyurl.com/ng2-components
@robianmcd
1 von 59

Recomendados

Angular performance slides von
Angular performance slidesAngular performance slides
Angular performance slidesDavid Barreto
3K views43 Folien
Angular JS2 Training Session #2 von
Angular JS2 Training Session #2Angular JS2 Training Session #2
Angular JS2 Training Session #2Paras Mendiratta
126 views45 Folien
How to perform debounce in react von
How to perform debounce in reactHow to perform debounce in react
How to perform debounce in reactBOSC Tech Labs
67 views22 Folien
Angular2 + rxjs von
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjsChristoffer Noring
2.4K views91 Folien
Workshop 26: React Native - The Native Side von
Workshop 26: React Native - The Native SideWorkshop 26: React Native - The Native Side
Workshop 26: React Native - The Native SideVisual Engineering
2.8K views54 Folien
Angular 2 introduction von
Angular 2 introductionAngular 2 introduction
Angular 2 introductionChristoffer Noring
363 views117 Folien

Más contenido relacionado

Was ist angesagt?

What's Coming in Spring 3.0 von
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0Matt Raible
6.1K views35 Folien
Workshop 17: EmberJS parte II von
Workshop 17: EmberJS parte IIWorkshop 17: EmberJS parte II
Workshop 17: EmberJS parte IIVisual Engineering
856 views54 Folien
Simplified Android Development with Simple-Stack von
Simplified Android Development with Simple-StackSimplified Android Development with Simple-Stack
Simplified Android Development with Simple-StackGabor Varadi
648 views72 Folien
Practical Protocol-Oriented-Programming von
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-ProgrammingNatasha Murashev
90.3K views66 Folien
Workshop 20: ReactJS Part II Flux Pattern & Redux von
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxVisual Engineering
1.2K views19 Folien
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac... von
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac..."Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...Fwdays
205 views112 Folien

Was ist angesagt?(20)

What's Coming in Spring 3.0 von Matt Raible
What's Coming in Spring 3.0What's Coming in Spring 3.0
What's Coming in Spring 3.0
Matt Raible6.1K views
Simplified Android Development with Simple-Stack von Gabor Varadi
Simplified Android Development with Simple-StackSimplified Android Development with Simple-Stack
Simplified Android Development with Simple-Stack
Gabor Varadi648 views
Practical Protocol-Oriented-Programming von Natasha Murashev
Practical Protocol-Oriented-ProgrammingPractical Protocol-Oriented-Programming
Practical Protocol-Oriented-Programming
Natasha Murashev90.3K views
Workshop 20: ReactJS Part II Flux Pattern & Redux von Visual Engineering
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
Visual Engineering1.2K views
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac... von Fwdays
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac..."Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
"Full Stack frameworks or a story about how to reconcile Front (good) and Bac...
Fwdays205 views
Building Web Interface On Rails von Wen-Tien Chang
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On Rails
Wen-Tien Chang2.7K views
Workshop 23: ReactJS, React & Redux testing von Visual Engineering
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
Visual Engineering1.8K views
ReactJs presentation von nishasowdri
ReactJs presentationReactJs presentation
ReactJs presentation
nishasowdri910 views
Developing New Widgets for your Views in Owl von Odoo
Developing New Widgets for your Views in OwlDeveloping New Widgets for your Views in Owl
Developing New Widgets for your Views in Owl
Odoo541 views
Jsp/Servlet von Sunil OS
Jsp/ServletJsp/Servlet
Jsp/Servlet
Sunil OS528K views
Architecting Single Activity Applications (With or Without Fragments) von Gabor Varadi
Architecting Single Activity Applications (With or Without Fragments)Architecting Single Activity Applications (With or Without Fragments)
Architecting Single Activity Applications (With or Without Fragments)
Gabor Varadi1.8K views
React Native: JS MVC Meetup #15 von Rob Gietema
React Native: JS MVC Meetup #15React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15
Rob Gietema729 views
State management in android applications von Gabor Varadi
State management in android applicationsState management in android applications
State management in android applications
Gabor Varadi484 views

Destacado

Social, Mobile & The Future of Retail von
Social, Mobile & The Future of RetailSocial, Mobile & The Future of Retail
Social, Mobile & The Future of RetailAmrita Chopra
2K views18 Folien
'Did He Really Say That?" effective component communication von
'Did He Really Say That?" effective component communication'Did He Really Say That?" effective component communication
'Did He Really Say That?" effective component communicationGus Sabatino
590 views17 Folien
7 Principles of Communications von
7 Principles of Communications7 Principles of Communications
7 Principles of Communicationsdexpan
277.5K views12 Folien
Dryland Systems Gender Component Communication von
 Dryland Systems Gender Component Communication Dryland Systems Gender Component Communication
Dryland Systems Gender Component CommunicationCGIAR Research Program on Dryland Systems
345 views6 Folien
React. Flux. Redux. by Andrey Kolodnitskiy von
React. Flux. Redux. by Andrey KolodnitskiyReact. Flux. Redux. by Andrey Kolodnitskiy
React. Flux. Redux. by Andrey KolodnitskiyValeriia Maliarenko
786 views38 Folien
Into the Land of lambda, One Programmer's Journey Into Functional Programming von
Into the Land of lambda, One Programmer's Journey Into Functional ProgrammingInto the Land of lambda, One Programmer's Journey Into Functional Programming
Into the Land of lambda, One Programmer's Journey Into Functional ProgrammingMike Pence
905 views25 Folien

Destacado(17)

Social, Mobile & The Future of Retail von Amrita Chopra
Social, Mobile & The Future of RetailSocial, Mobile & The Future of Retail
Social, Mobile & The Future of Retail
Amrita Chopra2K views
'Did He Really Say That?" effective component communication von Gus Sabatino
'Did He Really Say That?" effective component communication'Did He Really Say That?" effective component communication
'Did He Really Say That?" effective component communication
Gus Sabatino590 views
7 Principles of Communications von dexpan
7 Principles of Communications7 Principles of Communications
7 Principles of Communications
dexpan277.5K views
Into the Land of lambda, One Programmer's Journey Into Functional Programming von Mike Pence
Into the Land of lambda, One Programmer's Journey Into Functional ProgrammingInto the Land of lambda, One Programmer's Journey Into Functional Programming
Into the Land of lambda, One Programmer's Journey Into Functional Programming
Mike Pence905 views
Understanding Redux — Ilya Gelman von 500Tech
Understanding Redux — Ilya GelmanUnderstanding Redux — Ilya Gelman
Understanding Redux — Ilya Gelman
500Tech936 views
Social, Mobile & The Future of Retail von Amrita Chopra
Social, Mobile & The Future of RetailSocial, Mobile & The Future of Retail
Social, Mobile & The Future of Retail
Amrita Chopra3.6K views
Teaching Business Writing and Oral Communication von Bovee and Thill
Teaching Business Writing and Oral CommunicationTeaching Business Writing and Oral Communication
Teaching Business Writing and Oral Communication
Bovee and Thill925 views
Dumb and smart components + redux (1) von Brecht Billiet
Dumb and smart components + redux (1)Dumb and smart components + redux (1)
Dumb and smart components + redux (1)
Brecht Billiet2.2K views
Application architecture doesn't have to suck von jtregunna
Application architecture doesn't have to suckApplication architecture doesn't have to suck
Application architecture doesn't have to suck
jtregunna298 views
Derechos del niño von Tony Hotter
Derechos del niñoDerechos del niño
Derechos del niño
Tony Hotter148 views

Similar a Angular 2 Component Communication - Talk by Rob McDiarmid

Django Class-based views (Slovenian) von
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
1.1K views26 Folien
How to Bring Common UI Patterns to ADF von
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF Luc Bors
2.1K views54 Folien
Clean Javascript von
Clean JavascriptClean Javascript
Clean JavascriptRyunosuke SATO
16.8K views89 Folien
Codemotion appengine von
Codemotion appengineCodemotion appengine
Codemotion appengineIgnacio Coloma
2.4K views60 Folien
Week 12 code von
Week 12 codeWeek 12 code
Week 12 codeabhi7692271
287 views7 Folien

Similar a Angular 2 Component Communication - Talk by Rob McDiarmid(20)

Django Class-based views (Slovenian) von Luka Zakrajšek
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
Luka Zakrajšek1.1K views
How to Bring Common UI Patterns to ADF von Luc Bors
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
Luc Bors2.1K views
Symfony2 Building on Alpha / Beta technology von Daniel Knell
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell750 views
Easy rest service using PHP reflection api von Matthieu Aubry
Easy rest service using PHP reflection apiEasy rest service using PHP reflection api
Easy rest service using PHP reflection api
Matthieu Aubry42.5K views
준비하세요 Angular js 2.0 von Jeado Ko
준비하세요 Angular js 2.0준비하세요 Angular js 2.0
준비하세요 Angular js 2.0
Jeado Ko7K views
Symfony2 from the Trenches von Jonathan Wage
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
Jonathan Wage5.4K views
Юрий Буянов «Squeryl — ORM с человеческим лицом» von e-Legion
Юрий Буянов «Squeryl — ORM с человеческим лицом»Юрий Буянов «Squeryl — ORM с человеческим лицом»
Юрий Буянов «Squeryl — ORM с человеческим лицом»
e-Legion897 views
Dependency injection in Scala von Knoldus Inc.
Dependency injection in ScalaDependency injection in Scala
Dependency injection in Scala
Knoldus Inc.3.9K views
Action View Form Helpers - 2, Season 2 von RORLAB
Action View Form Helpers - 2, Season 2Action View Form Helpers - 2, Season 2
Action View Form Helpers - 2, Season 2
RORLAB1.3K views
Structuring React.js Components von Bartek Witczak
Structuring React.js ComponentsStructuring React.js Components
Structuring React.js Components
Bartek Witczak530 views
4Developers 2018: Structuring React components (Bartłomiej Witczak) von PROIDEA
4Developers 2018: Structuring React components (Bartłomiej Witczak)4Developers 2018: Structuring React components (Bartłomiej Witczak)
4Developers 2018: Structuring React components (Bartłomiej Witczak)
PROIDEA15 views
Building Large jQuery Applications von Rebecca Murphey
Building Large jQuery ApplicationsBuilding Large jQuery Applications
Building Large jQuery Applications
Rebecca Murphey7.8K views

Último

Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen... von
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...NUS-ISS
23 views70 Folien
Understanding GenAI/LLM and What is Google Offering - Felix Goh von
Understanding GenAI/LLM and What is Google Offering - Felix GohUnderstanding GenAI/LLM and What is Google Offering - Felix Goh
Understanding GenAI/LLM and What is Google Offering - Felix GohNUS-ISS
39 views33 Folien
Samsung: CMM-H Tiered Memory Solution with Built-in DRAM von
Samsung: CMM-H Tiered Memory Solution with Built-in DRAMSamsung: CMM-H Tiered Memory Solution with Built-in DRAM
Samsung: CMM-H Tiered Memory Solution with Built-in DRAMCXL Forum
105 views7 Folien
"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur von
"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur
"Thriving Culture in a Product Company — Practical Story", Volodymyr TsukurFwdays
40 views31 Folien
Java Platform Approach 1.0 - Picnic Meetup von
Java Platform Approach 1.0 - Picnic MeetupJava Platform Approach 1.0 - Picnic Meetup
Java Platform Approach 1.0 - Picnic MeetupRick Ossendrijver
25 views39 Folien
Future of Learning - Yap Aye Wee.pdf von
Future of Learning - Yap Aye Wee.pdfFuture of Learning - Yap Aye Wee.pdf
Future of Learning - Yap Aye Wee.pdfNUS-ISS
38 views11 Folien

Último(20)

Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen... von NUS-ISS
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...
Upskilling the Evolving Workforce with Digital Fluency for Tomorrow's Challen...
NUS-ISS23 views
Understanding GenAI/LLM and What is Google Offering - Felix Goh von NUS-ISS
Understanding GenAI/LLM and What is Google Offering - Felix GohUnderstanding GenAI/LLM and What is Google Offering - Felix Goh
Understanding GenAI/LLM and What is Google Offering - Felix Goh
NUS-ISS39 views
Samsung: CMM-H Tiered Memory Solution with Built-in DRAM von CXL Forum
Samsung: CMM-H Tiered Memory Solution with Built-in DRAMSamsung: CMM-H Tiered Memory Solution with Built-in DRAM
Samsung: CMM-H Tiered Memory Solution with Built-in DRAM
CXL Forum105 views
"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur von Fwdays
"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur
"Thriving Culture in a Product Company — Practical Story", Volodymyr Tsukur
Fwdays40 views
Future of Learning - Yap Aye Wee.pdf von NUS-ISS
Future of Learning - Yap Aye Wee.pdfFuture of Learning - Yap Aye Wee.pdf
Future of Learning - Yap Aye Wee.pdf
NUS-ISS38 views
Webinar : Competing for tomorrow’s leaders – How MENA insurers can win the wa... von The Digital Insurer
Webinar : Competing for tomorrow’s leaders – How MENA insurers can win the wa...Webinar : Competing for tomorrow’s leaders – How MENA insurers can win the wa...
Webinar : Competing for tomorrow’s leaders – How MENA insurers can win the wa...
Micron CXL product and architecture update von CXL Forum
Micron CXL product and architecture updateMicron CXL product and architecture update
Micron CXL product and architecture update
CXL Forum27 views
"Ukrainian Mobile Banking Scaling in Practice. From 0 to 100 and beyond", Vad... von Fwdays
"Ukrainian Mobile Banking Scaling in Practice. From 0 to 100 and beyond", Vad..."Ukrainian Mobile Banking Scaling in Practice. From 0 to 100 and beyond", Vad...
"Ukrainian Mobile Banking Scaling in Practice. From 0 to 100 and beyond", Vad...
Fwdays40 views
"Fast Start to Building on AWS", Igor Ivaniuk von Fwdays
"Fast Start to Building on AWS", Igor Ivaniuk"Fast Start to Building on AWS", Igor Ivaniuk
"Fast Start to Building on AWS", Igor Ivaniuk
Fwdays36 views
Five Things You SHOULD Know About Postman von Postman
Five Things You SHOULD Know About PostmanFive Things You SHOULD Know About Postman
Five Things You SHOULD Know About Postman
Postman25 views
The details of description: Techniques, tips, and tangents on alternative tex... von BookNet Canada
The details of description: Techniques, tips, and tangents on alternative tex...The details of description: Techniques, tips, and tangents on alternative tex...
The details of description: Techniques, tips, and tangents on alternative tex...
BookNet Canada110 views
MemVerge: Memory Viewer Software von CXL Forum
MemVerge: Memory Viewer SoftwareMemVerge: Memory Viewer Software
MemVerge: Memory Viewer Software
CXL Forum118 views
AI: mind, matter, meaning, metaphors, being, becoming, life values von Twain Liu 刘秋艳
AI: mind, matter, meaning, metaphors, being, becoming, life valuesAI: mind, matter, meaning, metaphors, being, becoming, life values
AI: mind, matter, meaning, metaphors, being, becoming, life values
.conf Go 2023 - Data analysis as a routine von Splunk
.conf Go 2023 - Data analysis as a routine.conf Go 2023 - Data analysis as a routine
.conf Go 2023 - Data analysis as a routine
Splunk90 views
JCon Live 2023 - Lice coding some integration problems von Bernd Ruecker
JCon Live 2023 - Lice coding some integration problemsJCon Live 2023 - Lice coding some integration problems
JCon Live 2023 - Lice coding some integration problems
Bernd Ruecker67 views
"Role of a CTO in software outsourcing company", Yuriy Nakonechnyy von Fwdays
"Role of a CTO in software outsourcing company", Yuriy Nakonechnyy"Role of a CTO in software outsourcing company", Yuriy Nakonechnyy
"Role of a CTO in software outsourcing company", Yuriy Nakonechnyy
Fwdays40 views

Angular 2 Component Communication - Talk by Rob McDiarmid

  • 2. What is a component
  • 3. @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. @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> wizardComp
  • 8. @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(); }
  • 11. @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. user.service.ts export class UserService { users: User[] = []; }
  • 14. user.service.ts export class UserService { private users$ = new BehaviorSubject([]); }
  • 15. user.service.ts export class UserService { private users$ = new BehaviorSubject([]); addUser(user) { let users = [user, ...this.users$.getValue()]; this.users$.next(users); } }
  • 16. 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); } }
  • 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); } getUsers() { return this.users$.asObservable(); } }
  • 18. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of filteredUsers"> <input #firstName (keyup)="filterUsers(firstName.value)"> </div> ` }) export class UserSearchComponent { filteredUsers: User[]; constructor(public userService: UserService) { } filterUsers(search) { this.filteredUsers = this.userService.users.filter(user => user.firstName.includes(search)); } }
  • 19. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of filteredUsers"> <input #firstName (keyup)="filterUsers(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; constructor(public userService: UserService) { this.users = userService.getUsers(); } filterUsers(search) { this.filteredUsers = this.userService.users.filter(user => user.firstName.includes(search)); } }
  • 20. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of filteredUsers"> <input #firstName (keyup)="filterUsers(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; constructor(public userService: UserService) { this.users = userService.getUsers(); } filterUsers(search) { this.filteredUsers = this.userService.users.filter(user => user.firstName.includes(search)); } }
  • 21. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of users | async"> <input #firstName (keyup)="filterUsers(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; constructor(public userService: UserService) { this.users = userService.getUsers(); } filterUsers(search) { this.filteredUsers = this.userService.users.filter(user => user.firstName.includes(search)); } }
  • 22. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of users | async"> <input #firstName (keyup)="filterUsers(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; constructor(public userService: UserService) { this.users = userService.getUsers(); } filterUsers(search) { this.filteredUsers = this.userService.users.filter(user => user.firstName.includes(search)); } }
  • 23. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of users | async"> <input #firstName (keyup)="firstNameSearch.next(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = userService.getUsers(); } }
  • 24. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of users | async"> <input #firstName (keyup)="firstNameSearch.next(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = userService.getUsers(); } }
  • 25. userSearch.component.ts @Component({ selector: 'user-search', template: ` <div *ngFor="let user of users | async"> <input #firstName (keyup)="firstNameSearch.next(firstName.value)"> </div> ` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { return users.filter(user => user.firstName.includes(search)); } ); }
  • 27. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.users = this.userService.users.filter(u => u !== user); this.filterUsers(this.firstName.nativeElement.value); } }
  • 28. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 29. List Search User Service users$ = BehaviorSubject([ 'User1', 'User2', 'User3' ])
  • 30. List Search User Service users$ = BehaviorSubject([ 'User1', 'User2', 'User3' ]) [ 'User1', 'User2', 'User3' ]
  • 31. List Search User1 ✖ User2 ✖ User3 ✖ User Service users$ = BehaviorSubject([ 'User1', 'User2', 'User3' ]) [ 'User1', 'User2', 'User3' ] User1 User2 User3
  • 32. List Search User1 ✖ User2 ✖ User3 ✖ User1 User2 User3 User Service users$ = BehaviorSubject([ 'User1', 'User2', 'User3' ]) removeUser('User2')
  • 33. List Search User1 ✖ User2 ✖ User3 ✖ User1 User2 User3 User Service users$ = BehaviorSubject([ 'User1', 'User3' ]) removeUser('User2')
  • 34. List Search User1 ✖ User2 ✖ User3 ✖ User1 User2 User3 User Service users$ = BehaviorSubject([ 'User1', 'User3' ]) [ 'User1', 'User3' ] removeUser('User2')
  • 35. List Search User1 ✖ User3 ✖ User1 User3 User Service users$ = BehaviorSubject([ 'User1', 'User3' ]) [ 'User1', 'User3' ] removeUser('User2')
  • 37. 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(); } };
  • 38. user.service.ts export const userReducer = (users = [], action) => { /* 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(); } */ };
  • 39. user.service.ts export const userReducer = (users = [], action) => { switch (action.type) { /* 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(); } */ } };
  • 40. user.service.ts export const userReducer = (users = [], action) => { switch (action.type) { case 'CREATE_USER': /* let users = [user, ...this.users$.getValue()]; this.users$.next(users); */ case 'DELETE_USER': /* let users = this.users$.getValue().filter(u => u !== user); this.users$.next(users); */ default: /* return this.users$.asObservable(); */ } };
  • 41. user.service.ts export const userReducer = (users = [], action) => { switch (action.type) { case 'CREATE_USER': return [...users, User.fromMockData()]; case 'DELETE_USER': /* let users = this.users$.getValue().filter(u => u !== user); this.users$.next(users); */ default: /* return this.users$.asObservable(); */ } };
  • 42. user.service.ts export const userReducer = (users = [], action) => { switch (action.type) { case 'CREATE_USER': return [...users, User.fromMockData()]; case 'DELETE_USER': return users.filter(user => user.id !== action.payload.id); default: /* return this.users$.asObservable(); */ } };
  • 43. user.service.ts export const userReducer = (users = [], action) => { switch (action.type) { case 'CREATE_USER': return [...users, User.fromMockData()]; case 'DELETE_USER': return users.filter(user => user.id !== action.payload.id); default: return users; } };
  • 44. app.module.ts import {userReducer} from "./reducers/userReducer"; @NgModule({ imports: [StoreModule.provideStore({ users: userReducer }) ], declarations: [/*...*/], providers: [/*...*/], bootstrap: [/*...*/] }) class AppModule { }
  • 45. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 46. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 47. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public userService: UserService) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 48. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public store: Store<AppState>) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 49. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public store: Store<AppState>) { this.users = Observable.combineLatest( userService.getUsers(), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 50. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public store: Store<AppState>) { this.users = Observable.combineLatest( store.select(s => s.users), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 51. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public store: Store<AppState>) { this.users = Observable.combineLatest( store.select(s => s.users), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.userService.removeUser(user); } }
  • 52. userSearch.component.ts @Component({ selector: 'user-search', template: `<div *ngFor="let user of users | async"> ... </div>` }) export class UserSearchComponent { users: Observable<User[]>; firstNameSearch = new BehaviorSubject(''); constructor(public store: Store<AppState>) { this.users = Observable.combineLatest( store.select(s => s.users), this.firstNameSearch, (users, search) => { ... } ); } removeUser(user: User) { this.store.dispatch({type: 'DELETE_USER', payload: {id: user.id}}); } }
  • 53. Takeaways - Everything is a component!!!
  • 54. 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()
  • 55. 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
  • 56. 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); }
  • 57. Takeaways - ngrx/store (Redux) - ngrx/store library brings redux like approach to Angular 2 - Centralized state - One way data flow
  • 58. 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