Hello 👋! Thanks for subscribing.
Published on: 2021-05-01
tags: Lab, Angular, TypeScript
I’m learning Angular right now – as a React.js fangirl.
Pluralsight offered a free month of learning in April. I’ve taken advantage of it.
Here are some notes on the course Angular Component Communication by Deborah Kurata.
Interpolation:
// src/app/app.component.ts
currentCustomer = 'Maria'
// src/app/app.component.html <h3>Current customer: <span style="color:#a6e22e">currentCustomer</span></h3>
Property Binding:
// src/app/app.component.ts
imageWidth: number = 50;
// src/app/app.component.html
<img [style.width.px]='imageWidth'>
Event Binding
// src/app/app.component.ts
toggleImage(): void {
this.showImage = !this.showImage;
}
// src/app/app.component.html
<button (click)='toggleImage()'>Show Image</button>
// src/app/app.component.ts
<p *ngIf="condition">Show this sentence unless the condition is true.</p>
- “two-way binding” between template and component
// src/app/app.component.ts
listFilter: string = 'Cart';
onFilterChange(filter:string): void {
this.listFilter = filter;
this.performFilter(this.listFilter);
}
// src/app/app.component.html
<input type='text' [ngModel]='listFilter' (ngModelChange)='onFilterChange=($event)' />
// src/app/app.component.ts
private _listFilter: string;
get listFilter(): string {
return this._listFilter;
}
set listFilter(value: string) {
this._listFilter = value;
}
// src/app/app.component.html
<input type='text' [(ngModel)]='listFilter' />
ViewChild and ViewChildren
valueChanges
observable
- ViewChild
- useful for template-driven forms
- remember that a component is first constructed (
constructor()
) and initialized(ngOnInit()
), after that the view initializes and renders
// src/app/app.component.ts
@ViewChild('filterElement') filterElementRef: ElementRef;
ngAfterViewInit(): void {
this.filterElementRef.nativeElement.focus();
}
// src/app/app.component.html
<input type='text' #filterElement [(ngModel)]='listFilter' />
NgAfterViewInit()
to access the native HTML element (DOM)// src/app/app.component.ts
listFilter: string;
@ViewChild(NgModel) filterInput: NgModel;
ngAfterViewInit(): void {
this.filterInput.valueChanges.subscribe(() => this.performFilter(this.listFilter));
}
// src/app/app.component.html
<input type='text' #filterElement [(ngModel)]='listFilter' />
- ViewChildren: returns a QueryList of element or directive references
- method does not work well with
*ngIf
: in this case the @ViewChild
might be undefined
Communicating with a Child Component
- parent component’s template must contain the child component
- components connected via routing don’t have a parent-child-relationship
// src/app/parent.component.html
<pm-criteria></pm-criteria>
// src/app/child.component.ts
@Component({
selector: 'pm-criteria',
templateUrl: './criteria.component.html',
styleUrls: ['./criteria.component.css']})
- push from parent to child:
@Input
, Getter/Setter, OnChanges
- pull from child to parent: Template Reference Variable,
@ViewChild
@Input
example:
// src/app/parent.component.html
<pm-criteria [displayDetail]='includeDetail'></pm-criteria>
// src/app/parent.component.ts
includeDetail: boolean = true;
// src/app/child.component.ts
@Input() displayDetail: boolean;
OnChanges
: favor if child reacts to any input property changes or if you need to access current and prior values@ViewChild
use from the parent’s class@Output
), provide information to parent (Template Reference Variable, @Viewchild
)// src/app/parent.component.html
<pm-criteria
[displayDetail]='includeDetail'
(valueChange)='onValueChange($event)'>
</pm-criteria>
// src/app/parent.component.ts
includeDetail: boolean = true;
onValueChange(value: string): void {
this.performFilter(value);
}
// src/app/child.component.ts
@Output() valueChange: EventEmitter<string> = new EventEmitter<string>();
private _listFilter: string;
get listFilter(): string {
return this._listFilter;
}
set listFilter(value: string) {
this._listFilter = value;
this.valueChange.emit(value);
}
// src/app/app.component.html
<input type='text' [(ngModel)]='listFilter' />
BehaviorSubject
), ngrx/ReduxExample Property Bag:
// src/app/param.service.ts
@Injectable()
export class ParamService {
showImage: boolean
filterBy: string
}
// src/app/product.list.component.ts
export class ProductListComponent {
get ShowImage(): boolean {
return this.paramService.showImage
}
get listFilter(): string {
return this.paramService.filterBy
}
set listFilter(value: string) {
this.paramservice.filterBy = value
}
}
// src/app/product.service.ts
private products: IProduct[];
getProducts(): Observable<IProduct[]> {
if (this.products) {
return of(this.products);
}
return this.http.get<IProduct[]>(this.productsUrl)
.pipe(
tap(data => console.log(JSON.stringify(data))),
tap(data => this.products = data),
catchError(this.handleError)
);
}
Subject
or BehaviorSubject
(multi-cast) to broadcast changes// src/app/product-list.component.html
<button type='button'
*ngFor='let product of products'
(click)='onSelected(product)'>
// src/app/product-list.component.ts
onSelected(product: IProduct) {
this.productService.changeSelectedProduct(product);
}
// src/app/product.service.ts
private selectedProductSource = new Subject<IProduct>();
selectedProductChanges$ = this.selectedProductSource.asObservable();
changeSelectedProduct(selectedProduct: IProduct) {
// broadcast the notification
this.selectedProductSource.next(selectedProduct);
}
// Component or Service
onSelected(product: IProduct) {
// listen for and respond to the notification
this.productService.changeSelectedProduct(product);
}
Communicating Using the Router
- route parameters: required, optional, query parameters
- benefits: simple, resulting URLs are bookmarkable & sharable
- cons: parameters appear in the URL, not good for large amounts of data
Thoughts
Deborah Kurata is an excellent teacher who can break concepts down to a digestible level.
The course slides and examples helped me immensely.
All in all, the class proved to be fantastic for people new to Angular.
I am sure that I will reference the course’s GitHub repository in the future.
Resources
- Angular Component Communication Pluralsight course by Deborah Kurata
- GitHub repository
Thank you for reading my blog posts.