我有一个(相当大而复杂)的Web应用程序。我们使用cordova将其包装在本机应用程序中。
我的问题是我有一个分割器元素,可以拖动它并调整旁边元素的大小。我从这个拆分器元素的拖动事件创建Observable,并在TypeScript中计算它旁边的元素的宽度,然后将其绑定到DOM元素,如下所示:
[style.width.%]="width$ | async"
我使用Observable和异步管道。我也试过一个简单的变量。
两者的问题是在cordova应用程序内部发生的速度非常慢。我检查每一行,一切都发生在浏览器的每一次计算和所有计算中,但当我将值推送到DOM(width$.next(calculatedWidth)
,或只是一个简单的值)时,它的发生速度不会像浏览器又名。它滞后了。我拖动分离器,然后我等待2-3秒,它只是跳到正确的位置。同时,浏览器中的相同代码也很好,可以在同一台设备上实时运行。
为了让事情变得更奇怪,我试着绕着变化检测工作,我直接操纵元素的宽度:
element.nativeElement.style.width = ...;
如果我这样做,那么变化就会立即发生。
非常感谢任何和所有帮助,因为在解决之前我不能继续前进。当然,我可以继续使用直接操作,但我也在应用程序的其他地方使用DOM绑定,而且它也一样慢,如果我在那里使用直接操作,那将会非常复杂和丑陋。
编辑:
以下解释的代码示例: http://pastebin.com/spHCjdLQ
清理事情。我正在使用Chrome和v56.x版本的System WebView的Android设备上测试它。
对于架构:
我有一个main-app.component,它有一个分割器,它控制着它左边的元素的宽度。事件处理和事件订阅是通过Observables
完成的Observable.fromEvent(this.splitter.nativeElement, 'mouseDown')...
在分离器的右侧,我有一个其他组件,比如说一个componentLoader。它使用*ngComponentOutlet
动态加载组件,并维护加载组件内部可用的服务,以检查它们可用的空间。为了使加载的组件响应大小更改,需要它。我知道我也可以在组件中实现它,但我在几种情况下需要它,我想避免重复。因此,我创建了一个服务,componentLoader将它提供给注入器并维护其中的值,并且加载的组件可以通过Observable监听更改。
组件加载器使用此方法监视其宽度:
ngDoCheck() {
let width = this.root.nativeElement.offsetWidth;
this.screenSizeService.width = Math.round(((width / window.innerWidth) * 100));
}
在每个更改检测圆上,它会刷新宽度。据我所知,这是使用Angular 2观察元素宽度的唯一方法,但它是一种hacky,所以如果有人知道其他方法,那么非常感谢!
问题在于,当我绑定分割元素的计数宽度时,另一个组件的宽度也会改变。并且两个检测运行都非常慢,但仅在cordova包装应用程序内部。在浏览器上它工作得很好。
系统WebView和Chore的版本在设备上是相同的:56.0.2924.87