angular - 当 ng2-nvd3 图表不可见时,浏览器会出现大小变化错误

标签 angular nvd3.js angular2-routing ng2-nvd3

在将 ng2-nvd3 与 Angular 2 路由功能结合使用时,我注意到控制台已满,并出现以下错误:

d3.min.js:1 Error: <g> attribute transform: Expected number, "translate(NaN,5)"

我设法将问题定位到一个用例:

  • 更改路线导出以指向带有 ng2-nvd3 海图的路线
  • 将其更改回指向没有 ng2-nvd3 海图的路线
  • 更改窗口的大小(或开发者控制台的大小)
  • 在控制台中查看错误

这可以通过 plunker 轻松重现:

  • 打开开发者控制台
  • 点击“图表”链接
  • 点击“无图表”链接
  • 更改开发者控制台(或浏览器窗口 - 效果相同)的大小 - 确保释放鼠标按钮而不仅仅是更改大小。
  • 控制台中出现错误

如何避免这一错误?

最佳答案

在 ng2-nvd3 source code第 118 行我们可以看到有一个正在注册的调整大小处理程序

self.chart.resizeHandler = nv.utils.windowResize(function() {...})

当图表消失时(如上面的情况),需要清除此调整大小处理程序 - 但它不会自动发生。

要解决这个问题,需要通过添加来获取对图表本身的引用

@ViewChild('chart') chart;

到组件(并通过向 nvd3 元素添加 #chart 属性来命名模板中的图表) 这将允许我们调用

this.chart.chart.resizeHandler.clear();

从调整大小事件中清除处理程序。 但我们仍然需要知道图表何时不在 View 中 - 有很多方法可以实现这一点,每种方法都有自己的微妙之处(ngOnDestroy/ngOnChanges 等)。 对我有用的方法虽然有点激进,但完全解决了问题:

我已将根路由器注入(inject)主组件并订阅其上的更改,通过带有 EventEmitter 的服务委托(delegate)它们 然后,我将该服务注入(inject)到图表组件中并注册到该事件(据我检查,您不能只是将路由器注入(inject)到图表组件中,因为它不会是根路由器,而是一些子路由器和因此不会得到所有的路线变化) 在事件处理程序中,我创建了一次性调用

this.chart.chart.resizeHandler.clear();

路由服务:

import { Injectable, EventEmitter } from 'angular2/core';

@Injectable()
export class RoutingService {
    public onRouteChange$: EventEmitter<string>;

    constructor() {
        this.onRouteChange$ = new EventEmitter();
    }

    routeChange(route: string) {
        this.onRouteChange$.emit(route);
    }
}

MainComponent 构造函数:

  constructor(private router:Router, private routingService:RoutingService){
    router.subscribe( val => routingService.routeChange(val));
  }

ChartComponent 构造函数:

  constructor(private routingService:RoutingService) {
    let sub:any = routingService.onRouteChange$.subscribe(route => {
        if (route != 'chart') {
            this.chart.chart.resizeHandler.clear();
            if (sub) {
              sub.unsubscribe();
            }
        }
    });
  }

你可以在这个plunker中看到它

关于angular - 当 ng2-nvd3 图表不可见时,浏览器会出现大小变化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36977176/

相关文章:

angular - 在与 parent 相同的路由器 socket 中使用子路由

java - 当请求的凭证模式为 '*' 时,响应中的 header 不能是通配符 'include'

javascript - nvd3 工具提示十进制格式

javascript - 相同时间戳的 nvd3 正值和负值

javascript - 如何在nvd3图表上显示不同范围的2条线

Angular 2 获取父路由

使用 routerLink 的 Angular 2 单元测试组件

angular - 如何使 Angular Ivy + Angular Universal 工作?

angular - @Query 在搜索 TemplateRef 时表现不同

angular - IONIC 3 - Admob Free 在测试错误时不显示广告