7

I have one parent and one child component. If the child component updates its value internally I am unable to update value back from Parent.

See the example in this Stackblitz: https://stackblitz.com/edit/angular-ivy-tynepp. When the child component loses focus I fire an event and the parent resets value of the child component. But I think that because the parent's "this.value" didn't change that the update doesn't trigger detection changes in the child.

How can I solve this dilemma?

greybeard
  • 2,249
  • 8
  • 30
  • 66
Andrei V
  • 1,468
  • 3
  • 17
  • 32

4 Answers4

12

As you said, change detection is not triggered because the bound value has not changed. You can force an update of the data binding with the following steps:

  1. Set a temporary value
  2. Call ChangeDetectorRef.detectChanges()
  3. Reset the value
constructor(private changeDetectorRef: ChangeDetectorRef) {}

resetValue() {
  this.value = "____TempValue____";
  this.changeDetectorRef.detectChanges();
  this.value = "";
}

See this stackblitz for a demo.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • 1
    bit hackish but did the trick. thank you @ConnorsFan. Im surprised that there is no cleaner solution to this – Andrei V Jun 03 '20 at 03:17
  • You Are a Master Bro. After whole day, finally it was only solution which worked for me, to dynamically disable option of ng-select, from triggered method in component. Thanks a lot. – 10101101 May 26 '22 at 23:41
3

I have created a Directive for my project and it's really easy to use

<ng-container *rerender='changingInput'>
  this content will be re-rendered everytime `changingInput` changes
</ng-container>

Check out my Gist for more details.

Anh Nguyen
  • 1,202
  • 14
  • 17
0

Another simpler approach to get this can be to use the template variables as you can see in the example below:

parent.component.html

<app-my-child 
  #child
  (lostFocus)="child.value = ''"></app-my-child>

Solution available here.

bjdose
  • 1,269
  • 8
  • 10
  • looks like this solution only works for the 1st time when focus is lost. after that its not reset. @bjdose – Andrei V Jun 03 '20 at 03:15
0

Here is another simple trick.

The browser/Angular does not detect well changes of primitives. If you rely on that, you can change your primitive to an object. Angular detects object changes much better.

For example:

If you have in ts:

refreshOnThisValue: number = 0;

and in HTTP view:

<ng-container *ngIf="refreshOnThisValue">

   ... render something

   show value: {{ refreshOnThisValue }}

</ng-container>

Change it in ts:

refreshOnThisValue: Number = new Number(0);

and somewhere in the ts code, where the value needs change and to trigger the refresh enter:

                  // newValue is the new number

this.refreshOnThisValue = new Number(newValue);

and in HTTP view:

<ng-container *ngIf="refreshOnThisValue">

   ... render something

   show value: {{ refreshOnThisValue.valueOf() }}

</ng-container>
Felix
  • 1,662
  • 2
  • 18
  • 37