您可能已经找到了解决方案,但我最近正好遇到了这个问题,发现这个问题没有答案。
关键似乎是您注册事件通知的时间。在 iframe 的 onload 事件触发后,您必须注册滚动事件。在我的代码中,我在模板代码中注册了 iframe 的 onload 事件。
<form ngNoForm action="/logout" method="post" role="form">
<div class="container-fluid main">
<iframe #tframe [src]="src" class="frame" (load)="onFrameLoad()"> </iframe>
<div class="clearfix">
<div class="pull-right">
<button type="submit" class="btn btn-dialog-secondary">{{'common.decline' | i18n}}</button>
<button type="button" [disabled]="!scrollBottom" id="defaultFocus" class="btn btn-primary" (click)="accept()">{{'common.accept' | i18n}}</button>
</div>
</div>
</div>
</form>
在类本身中,我有 iframe ElementRef 成员(以及我想要更新以响应滚动事件的布尔成员,
稍后将在此答案中详细介绍..)。
export class RouteFrame implements AfterViewInit {
scrollBottom: boolean = false;
@ViewChild('tframe') frame : ElementRef;
scroll$: any = null;
}
然后在RouteFrame类的onFrameLoad()方法中注册滚动事件。
onFrameLoad() {
this.scroll$ = Observable.fromEvent(this.frame.nativeElement.contentWindow, 'scroll')
.debounceTime(200)
.subscribe((evt: any) => {
this.onScroll();
});
}
然后在 onScroll() 方法中,做任何你需要的逻辑。就我而言,当用户滚动到 iframe 底部时,我正在观看。
然而,我发现滚动事件发生在 Angular 的“外部”,因此 Angular 会根据该变量的值变化重新评估表单,因此即使接受按钮也从未启用
将 [disabled]="!scrollBottom" 作为其声明的一部分。因此,为什么对 scrollBottom 变量的更新包含在 this.zone.run() 中。
onScroll() {
if (this.frame.nativeElement.contentWindow.scrollY > this.frame.nativeElement.contentWindow.innerHeight) {
this.zone.run(() => {
this.scrollBottom = true;
});
}
}
this.zone 就像其他 Angular 提供程序一样注入到 RouteFrame 类的 cstr 中。
constructor(@Inject(NgZone) private zone: NgZone, ....)
为了完整性,在组件完成时取消订阅滚动事件监听器。
NgOnDestroy() {
this.scroll$.unsubscribe();
}
Angular 4.3.0 版