具有双向绑定的Angular2组件输入不会触发change事件

时间:2017-04-09 20:03:40

标签: angular

我有一个paginator组件来显示页面列表并检测用户何时单击以显示另一个页面并且此组件不更改页面只能触发事件但我无法观察更改事件。

该组件具有双向绑定以宣布当前页面已更改并正常工作,因为我可以在更改后显示html中的值(请参阅HTML中的

)。

如何在更改分页器组件中的当前页面后执行页面更改?

我阅读了以下https://stackoverflow.com/questions/36150107/angular-2-change-event-model-changes但在我的案例中无效。

HTML(使用分页器):

<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组件):

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组件):

<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>

2 个答案:

答案 0 :(得分:1)

当您使用currentPageChange作为输出变量时,您应使用相同的方法来处理事件

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

<p>{{currentPage}}</p> <!--Work Fine showing the new page selected!-->

答案 1 :(得分:0)

我知道这个问题永远存在,但是昨天我在试图弄清楚如何使它工作时偶然发现了这个问题。

我认为在给定示例中缺少的OP是您应该在setter方法中为目标属性发出新值,如下所示:

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>();

仅通过适当命名的EventEmitter发出新值不足以使属性双向绑定。您需要发出事件作为设置值的副作用 -实现该问题的方法是通过set方法。

这是一个最小的StackBlitz示例,演示了实际的效果:https://stackblitz.com/edit/angular-l9d89t

当值在一个位置(父组件或子组件)更改时,它将在两个位置无缝更新。魔术!