2

I have one paginator component to show the page list and detect when the user click to show another page and this component not change the page only must be trigger the event but I cannot watch the change event.

The component has an two-way binding to announce the current page changed and work fine because I can show the value in the html after change (please, see

in the HTML).

How I can execute the page change after change the current page in the paginator component?

I read the following Angular 2 change event - model changes but not work in my case.

HTML (using the paginator):

<paginator [pageCount]=pageCount [(currentPage)]=currentPage (ngModelChange)="pageChanged($event)"></paginator> <!--pageChanged is not called-->
<p>{{currentPage}}</p> <!--Work Fine showing the new page selected!-->

TS (paginator component):

import { Component, OnInit, OnChanges, SimpleChanges, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';

@Component({
  selector: 'paginator',
  templateUrl: './paginator.component.html',
  styleUrls: ['./paginator.component.css']
})
export class PaginatorComponent implements OnInit, OnChanges {

  pageList : number[] = [1];  

  @Input()  pageCount   : number = 1;
  @Input()  currentPage : number = 1; 
  @Output() currentPageChange = new EventEmitter<number>();

  constructor(private ref:ChangeDetectorRef) {}

  ngOnInit() 
  {
    this.loadPageList();
  }

  ngOnChanges(changes: SimpleChanges)
  {
    this.loadPageList();
  }

  changePage(page : number)
  {
    if(page < 1)
        return;

    if(page > 1 && page > this.pageCount)
      return;

    if(this.currentPage == page)
      return;

    this.currentPage = page;

    this.currentPageChange.emit(this.currentPage);    
  }

  private loadPageList()
  {
      if(this.pageCount < 1)
        this.pageCount = 1;

      let pages = [1];

      for(let p = 2; p <= this.pageCount; p++)
        pages.push(p);

      this.pageList = pages;

      this.ref.detectChanges();          
  }
}

HTML (paginator component):

<div class="row">
    <div class="col-md-12 text-center">
        <ul class="pagination">
            <li><a (click)="changePage(1)">&laquo;</a></li>
            <li><a (click)="changePage(currentPage - 1)">&#10094;</a></li>
            <li *ngFor="let page of pageList" [class.active]="currentPage==page">
                <a id="changePage{{page}}" (click)="changePage(page)">{{page}}</a>
            </li>
            <li><a (click)="changePage(currentPage + 1)">&#10095;</a></li>
            <li><a (click)="changePage(pageCount)">&raquo;</a></li>
        </ul>
    </div>
</div>
Glorfindel
  • 21,988
  • 13
  • 81
  • 109

2 Answers2

0

I know this question is forever old, but I stumbled onto this question yesterday while trying to figure out how to get this working.

I think what the OP is missing in the given example is that you should emit the new value in a setter method for the target property, like this:

private _currentPage: number = 1;

@Input() get currentPage(): number {
  return this._currentPage;
}

set currentPage(value: number) {
  this._currentPage = value;
  this.currentPageChange.emit(value);
}

@Output() currentPageChange = new EventEmitter<number>();

Simply emitting a new value through an appropriately named EventEmitter is not enough to make the property two-way bound. You need to be emitting the event as a side-effect of setting the value — the way to do that is through a set method.

Here's a minimal StackBlitz example that demonstrates the effect in action: https://stackblitz.com/edit/angular-l9d89t

When the value changes in one place (either the parent or the child component), it seamlessly updates in both places. Magic!

dannymcgee
  • 621
  • 2
  • 9
  • 16
  • In my case it didn't work with set and get. So i haf to replace settter and getter with and attribute and move the emitter away from the setter. – Viktor Reinok Aug 17 '23 at 14:17
-1

As you are using currentPageChange as your output variable you should use the same to handle the event

<paginator [pageCount]=pageCount [currentPage]="currentPage"
         (currentPageChange)="pageChanged($event)"></paginator> 

<p>{{currentPage}}</p> <!--Work Fine showing the new page selected!-->
Aravind
  • 40,391
  • 16
  • 91
  • 110
  • 2
    This is not the correct answer. Two-way data binding, which is what OP was asking about, is designed to work with the `[(property)]` syntax. Adding the "Change" suffix to the `Output` name is how you're supposed to signal to Angular that a property should be two-way bound instead of needing to hook into the `Output` event and handle it manually. – dannymcgee Oct 10 '19 at 19:39