1

使用Angular 4。我有一个从它的父组件paging.component获取页码pageSize (在它获取数据之后)。

将使用生命周期钩子paging.component查找对 ' 的更改。@InputOnChanges

paging.component也有一个<select>输入,您可以在其中更改pageSize

在此OnInit阶段,<select>将设置为从父组件传入的pageSize 。

如果你改变pageSize<select>一切正常,但我有时也想将pageSize从父组件更改为不同的值(如原始值)。

当我改变pageSize时,它​​不会更改<select>输入。(即使其他一切似乎都正常工作)。

我尝试将以下代码添加到ngOnChanges方法中:

if (this.pageSizeFG) {
    this.pageSizeCtrl.setValue(this.pagesize);
}

但是,这会产生错误:

ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:“假”。当前值:“真”。

如果我尝试转到其他页面,分页似乎也会不断将自身重置到第 1 页。

我研究了一些其他的生命周期钩子ChangeDetectorRef,和ngZone,但这些似乎使问题变得更糟。

我在这里创建了一个plnkr 来演示错误。

如果您去paging.component.ts并用 注释掉该行,this.pageSizeCtrl.setValue(this.pagesize);那么一切正常,除了<select>不更新。

4

1 回答 1

1

这是由您ngModelChange在选择元素上的事件 + 您的 ngOnchanges 生命周期方法引起的。

<select (ngModelChange)="setPageSize($event)">...</select>

正在发生的事情是

  1. 您将新输入传递给 paging.component
  2. ngOnChanges 触发
  3. 在 ngOnChanges 中,this.pageSizeCtrl.setValue(this.pagesize) 触发
  4. 这会导致触发 ngModelChange 事件 (setPageSize)
  5. setPageSize 发射到父组件
  6. parent 更改导致 ngOnChanges 再次触发的输入。

所以这一切都导致了 Expression has changed 错误。

为了解决这个问题,我会使用 change 事件而不是 ngModelChange

<select (change)="setPageSize()">...</select>

这种方式setValue()不会导致setPageSize()事件触发。您还需要更新属性setPageSize()的发射方式pageSize

setPageSize() {
    // get pageSizeCtrl value programatically
    let pageSize = +this.pageSizeCtrl.value;
    this.pagechange.emit({ page: 1, pageSize: pageSize });
}

这是一个带有修复程序的工作 plnkr ( http://plnkr.co/edit/zJEIYJzG5OGRXIfA77Qz?p=preview )

于 2017-11-08T04:07:28.673 回答