user3366195
user3366195

Reputation: 99

How to force change detection on input when input value doesn't change

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

Answers (2)

dev-dan
dev-dan

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

Ben Racicot
Ben Racicot

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

Related Questions