Reputation: 99
Currently on Angular 7. A component input is a boolean value that may stay the same after falling into and out of an indeterminate state.
For example: I have expandable rows that can be opened individually or all at once.
this.expand will be false initially.
pass this.expand = true to open all rows
user collapses each row individually
pass this.expand = true and nothing happens. no change is detected.
the code will display how I handle this through a settimeout() but am looking for a cleaner solution.
expandAll() {
// if 'expanded' is already true we have to force push the update
if (this.expanded) {
this.expanded = false;
setTimeout(() => {
this.expanded = true;
}, 0);
} else {
this.expanded = true;
}
}
Hoping to force change detection without using this async code.
Upvotes: 3
Views: 6393
Reputation: 6283
Hoping to force change detection without using this async code.
This is where you could take advantage of Angular change detection, try the following code, this will be forcing change detection to run manually and take into account the toggle of the Boolean value.
In turn propagating the changes into the DOM.
import { ChangeDetectorRef } from '@angular/core';
constructor(private ref: ChangeDetectorRef){}
public expandAll(): void
{
this.expanded = !this.expanded; // toggles Boolean value
this.ref.detectChanges(); // forces change detection to run
}
Change Detection Ref from the Angular docs.
Upvotes: 2
Reputation: 5893
Create an event with EventEmitter, this may have to become dynamic if you have many dropdowns but will solve your change event issue.
// ChildComponent
@Output() dropdown: EventEmitter<string> = new EventEmitter();
// trigger the event to 'emit' the output event
onClickDropdown(e): void {
this.dropdown.emit('the string to be emitted');
}
View
<dropdown (dropdown)="onClickDropdown($event)">
You could also watch for clicks with @Hostlistener. See my StackBlitz example.
I'll be here if you need more help, just comment or message me.
Upvotes: 0