3

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.

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I wonder if this works. If it is a simple value (number, string, boolean) that didn't change, then change detection might be forced to run but no change(s) is detected where the @Input property won't "fire". Which in my case is desired (or I should overthink my requirement and stumble upon a design flaw at my side 😉)
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.