2

I have an Angular Custom scroll directive with an @Input() where I am passing an HTML element as a parameter to move the scrollbar to that specific HTML Element.

With this approach, if I pass the same HTML Element multiple times, the Input detecting changes only for the first time after that it is not detecting any changes.

Is there any way to force Angular to detect change for the same input?

@Input() set elementToScroll(element: HTMLElement) {
    if (element != undefined) {
        console.log(element); // Detecting first time only for same input
        this._osInstance?.scroll(
            { el: element, block: { y: 'begin' } },
            500
        );
    }
}
RAHUL KUNDU
  • 745
  • 2
  • 12
  • 33
  • Angular change detection works only when input value changed by address, it is working expected, for the same value, it can not considered. Is this a valid use case ? detecting change for the same input ? Think like angular change detection goes from top to bottom in tree and if you keep asking for change detection for same value, angular need to run those change detection unnecessary, and it will cause a performance issue in long run. – Abhinav Kumar Jul 27 '21 at 05:35
  • Which change detection strategy are you using? On default, it only matters when the values get changed and angular runs the changes from root to all its child provided that something changes in the component. On Push, only works when we pass new reference to the data-bound Input properties. You should check [this](https://www.telerik.com/blogs/simplifying-angular-change-detection) link as it is important to understand the change detection. – Apoorva Chikara Jul 27 '21 at 06:00

2 Answers2

2

You can also use a "trick", pass to your input an object {element:element}

@Input() set elementToScroll(element:{element:HTMLElement}) {
    //use element.element
    if (element.element != undefined) {
        console.log(element.element); 
        this._osInstance?.scroll(
            { el: element.element, block: { y: 'begin' } },
            500
        );
    }
}

//in your parent you has some like:

@ViewChild('move') myElement:ElementRef
click(){
   this.parameter={element:myElement.nativeElement}
}
Eliseo
  • 50,109
  • 4
  • 29
  • 67
0

Extend your component with the interface OnChanges and implement the ngOnChanges method:

ngOnChanges(changes: SimpleChanges) {
    if(changes['myProperty']) {
        // myProperty has changed
   }
}

If you set the same value twice then depending on the type of value this solution works or will be triggered only once.

  • If the type of myProperty is string, number, ... then it will be triggered only once
  • If the type is complex then the solution works.

See the console output for the following sample: https://stackblitz.com/edit/angular-ivy-rd8szx

Michael Mairegger
  • 6,833
  • 28
  • 41
  • does it detect change when the value even doesn't change ? As per doc it says , A lifecycle hook that is called when any data-bound property of a directive changes. Define an ngOnChanges() method to handle the changes. – Abhinav Kumar Jul 27 '21 at 05:37
  • @AbhinavKumar depends: If the type of property is simple (i.e. string, number,...) then it will not work. Otherwise yes. I will update the answer with that information – Michael Mairegger Jul 27 '21 at 05:53