2

Here's my scenario:

I have a component, configured with the OnPush strategy, that displays a PDF document, page by page, and allows the user to scroll through pages and navigate to a certain page. It also exposes an input property scrollToPage which allows the parent to navigate to a certain page.

@Component({
    selector: 'pdf-document',
    templateUrl: './pdf-document.component.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PdfDocumentComponent implements OnChanges {
    @Input() scrollToPage: number;
    
    ngOnChanges(changes: SimpleChanges) {
        if (changes.scrollToPage) {
            this.goToPage(this.scrollToPage);
        }
    }

    public goToPage(page: number) {
        ...
    }
}

All works as expected, except for one scenario:

  1. Parent sets the scrollToPage input to, let's say, number 2
  2. The ngOnChanges triggers and scrolls to page 2
  3. The user navigates to another page inside the PdfDocumentComponent (the goToPage function is called from the view)
  4. The parent sets again the scrollToPage input to number 2

In this case, the ngOnChanges is not triggered and the goToPage function is not called, because the previous value of scrollToPage is the same, number 2.

To fix this problem I can only see 3 options, but none of them seem appropriate and are more or less hacks:

  1. Change the input type to be an object and always send a new reference. (I don't like this because it doesn't make sense to send an object when I really want it to send a simple number)
  2. Use @ViewChild in the parent to get a reference to the child component and call from there the goToPage function. (I don't like this because I want to keep my component's contract with the outside as clear as possible - using only @input and @output properties. Otherwise, I have to document these public functions too.)
  3. Change the OnPush strategy to Default. (This is actually not an option for me)

Do you guys know any other solutions to this problem? Is there a more elegant way of solving it?

Sergiu
  • 1,397
  • 1
  • 18
  • 33

1 Answers1

-1

You can you KeyDown event. it is executed when user press a key.

<input type="text" (keydown)="onKeyDownEvent($event)" /> 

here is detail of keyboard events in JavaScript which you can use for this purpose. [1]: onKeyPress Vs. onKeyUp and onKeyDown

Muhammad Nasir
  • 2,126
  • 4
  • 35
  • 63
  • I don't think you've understood my question. My problem is with the Angular component input, and not with an HTML input. If I send twice the same number to a component the ngOnChanges triggers only once. – Sergiu Mar 16 '21 at 07:04