我有一个包含10个标记的Google地图,并在页面中添加了Angular2 SideNav,如下所示:
<mat-sidenav-container>
<div id="map">Google Map [Code omitted]</div>
<mat-sidenav #sidenav position="end" align="end" class="user-sidenav"></mat-sidenav>
</mat-sidenav-container>`
在我的组件中,我有:
@ViewChild(MatSidenav) sidenav: MatSidenav;
// ...
每个标记都添加了一个事件监听器,其代码如下:
google.maps.event.addListener(gmr, 'click', (function(marker) {
return function() {
self.handleMarkerClick(marker);
};
})(gmr));
gmr
是google.maps.Marker
和self
= this
handleMarkerClick
看起来像这样:
private handleMarkerClick(marker: any) {
this.sidenav.open();
console.log('sidenav open');
}
它唯一能做的就是打开一个Angular Material Sidenav。单击标记后,侧面打开前会有2-3秒的延迟。在console.log()
的帮助下,我可以看到'sidenav open'是在我点击标记的同一瞬间打印出来的,但是sidenav动画在2-3秒后开始。
出于测试目的,我在HTML中添加了一个按钮:
<button mat-button (click)="sidenav.toggle()">Open sidenav</button>
sidenav会立即打开。
有没有人知道为什么从组件打开sidenav而不是从HTML打开sidenav会有延迟?
编辑:延迟范围为1到3秒。有时它更快,有时它很慢。
Edit2:我做了另一个测试并提出了一个自定义sidenav解决方案(一些html,动画等基本上复制了Angular Material sidenav)。从组件调用时它仍然很慢,因此它不是Angular Material问题。有线索吗?
答案 0 :(得分:0)
我已经知道发生了什么。
我做的第一件事就是重新编写的代码,甚至可以将监听器添加到谷歌标记中:
gmr.addListener('click', () => {
this.handleMarkerClick(gmr);
});
然后我注意到Zone.js发生了很多事情。我不知道它是什么。
区域是在异步任务中持续存在的执行上下文。您 可以将其视为JavaScript VM的线程本地存储。 [来自github.com/angular/zone.js]
原来用户界面无法正常更新,因为sidenav
(在handleMarkerClick()
中更新)会在Angular的区域之外更新。因此,我们必须包含this.zone.run
才能获得正确的更新:
gmr.addListener('click', () => {
this.zone.run(() => {
this.handleMarkerClick(gmr);
});
});
NgZone
需要包含在类构造函数中添加的'@angular/core'
和zone
变量中。
地图正在飞行,事件处理程序切换sidenav面板,完全没有延迟。