angular - D3,Typescript - 类型 'this' 的参数不可分配给类型 'BaseType' 的参数

标签 angular typescript d3.js

我这里有 stackbiltz - https://stackblitz.com/edit/lable-line-break-vaszab?file=src/app/app.component.ts

我在 Angular 应用程序中有一个 d3 条形图。

使用在创建 z 轴刻度时调用的函数将 x 轴标签分成两行

private insertLinebreak(d) {

    let labels = d3.select(this);
    let words = d;
    console.log("Label:", labels.html());
    labels.text('');

    let index = words.indexOf(' ', words.indexOf(' ') + 1)
    let title = words.substr(0, index)
    let subtitle = words.substr(index + 1)

    let tspantitle = labels.append('tspan').text(title)
    let tspansubtitle = labels.append('tspan').text(subtitle)
    tspantitle
      .attr('x', 0)
      .attr('dy', '15')
      .attr('class', 'x-axis-title');
    tspansubtitle
      .attr('x', 0)
      .attr('dy', '16')
      .attr('class', 'x-axis-subtitle');

  };

该函数使用“this”来选择调用该函数的“g”(但在 d3 中我认为它选择了整个 svg)

此代码在 stackblitz 中有效,但在我的实际代码中出现错误

Argument of type 'this' is not assignable to parameter of type 'BaseType'.

我知道这不是很有用

我认为这与 Typescript 及其处理“this”的方式有关

有谁知道为什么会这样以及我该如何解决这个问题。

最佳答案

编译器将 insertLinebreak() 函数内的 this 的类型推断为您的类 StackedChartCompoent。看着 type definitions但是,对于 d3.select(node),您可以看到它希望节点扩展 BaseType,即 defined作为

export type BaseType = Element | EnterElement | Document | Window | null;

因为你的类显然没有扩展这个 BaseType 你得到了错误。

基本上有两种解决方法:

  1. 如果你只在一个地方需要insertLinebreak()方法,即作为.each()的回调,你可以把它做成一个函数表达式然后直接作为参数传递给 .each()

    .each(function() {
      let labels = d3.select(this);   // works
      // ...the original method's body
    })
    

    这是有效的,因为编译器现在知道这个函数的单一入口点,并且可以推断 this 的类型,因为 .each()使用 Function.prototype.call()this 绑定(bind)到节点。

    但请记住,您必须使用经典函数表达式来支持 ES6 箭头函数,因为那样会使 this 再次指向其词法范围而不是指向节点。

  2. 幸运的是,TypeScript 本身内置了一种更惯用的方法。自 version 2.0你可以提供一个假的this parameter作为函数参数列表中的第一项。此参数告诉编译器 this 在所述函数内部指的是什么。因此,您的代码可以重写为:

    private insertLinebreak(this: SVGTextElement) {
      let labels = d3.select(this);   // works
      // method body left untouched
    }
    

关于angular - D3,Typescript - 类型 'this' 的参数不可分配给类型 'BaseType' 的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53855394/

相关文章:

javascript - 找到合成属性@enterAnimation。请在您的申请中包含 "BrowserAnimationsModule"或 "NoopAnimationsModule"。 Angular 4

javascript - 在 Angular 2 中订阅后未定义值,但在 templateurl 中它可以显示

javascript - D3 添加所需类型的输入

Angular2 Observable - 如何包装第三方 ajax 调用

javascript - 如何在 ng-container Angular 2 中渲染数组中的数据?

Angular 路由参数 'state' 在类型 'NavigationExtras 中不存在

javascript - 超时后在 svg.node() 上调用 d3.mouse

html - 如何在点击时更改按钮颜色?

angular - 何时取消订阅 `route.params` observable

d3.js - 如何在 nvd3 分组多条形图中的分组条形图中的条形之间添加空间?