这是我的场景:
我有一个配置了 OnPush 策略的组件,它逐页显示 PDF 文档,并允许用户滚动页面并导航到某个页面。它还公开了一个输入属性scrollToPage
,该属性允许父级导航到某个页面。
@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) {
...
}
}
一切都按预期工作,除了一种情况:
- 父母将
scrollToPage
输入设置为,比如说,数字 2 - ngOnChanges 触发并滚动到第 2 页
- 用户导航到 PdfDocumentComponent 内的另一个页面(从视图调用 goToPage 函数)
- 父母再次将
scrollToPage
输入设置为数字 2
在这种情况下,ngOnChanges
不会触发 并且goToPage
不会调用函数,因为之前的值scrollToPage
是相同的,数字 2。
要解决这个问题,我只能看到 3 个选项,但它们似乎都不合适,而且或多或少是 hack:
- 将输入类型更改为对象并始终发送新引用。(我不喜欢这样,因为当我真的希望它发送一个简单的数字时发送一个对象没有意义)
- 在父组件中使用
@ViewChild
以获取对子组件的引用并从那里调用该goToPage
函数。(我不喜欢这样,因为我想尽可能清楚地保持我的组件与外部的合同 - 仅使用 @input 和 @output 属性。否则,我也必须记录这些公共函数。) - 将 OnPush 策略更改为 Default。(这实际上不是我的选择)
你们知道这个问题的任何其他解决方案吗?有没有更优雅的解决方法?