键入

时间:2016-08-18 04:48:11

标签: d3.js dart dart-js-interop

我已经定义了一个D3 Dart JS Interop,我用它来设置D3对象的值并调用它们,这很好用。不幸的是,D3对setter和getter使用相同的函数,并且取决于将它们分开的参数量。

例如,Arc对象能够像这样设置和获取InnerRadius(在JavaScript中):

var arc = d3.arc().innerRadius(25);
//arc with innerRadius of 25
var radius = arc.innerRadius();
//radius is 25

我定义的Dart包装器如下所示:

@JS('d3')
library d3;

import 'dart:js';
import "package:js/js.dart";

@JS("arc")
class Arc {
  external Arc innerRadius(num innerRadius);
  external Arc();
}

我想定义一个这样的包装器:

@JS("arc")
class Arc {
  external Arc innerRadius(num innerRadius);
  external num innerRadius();
  external Arc();
}

但它抱怨已经定义的名称。如何定义飞镖包装器以便我可以在键入时设置和调用该值?

D3定义了一个像这样的Arc:

function arcInnerRadius(d) {
    return d.innerRadius;
}

function constant$1(x) {
    return function constant() {
        return x;
    }
}

function arc() {
    var innerRadius = arcInnerRadius;

    function arc() {
        var r0 = +innerRadius.apply(this, arguments);
        //calculate and return path
    }

    arc.innerRadius = function(_) {
        if(arguments.length) {
            if(_ === "function") {
                innerRadius = _;
            } else {
                innerRadius = constant$1(+_);
            }
            return arc;
        }
        return innerRadius;
    }

    return arc;
}

因此,getter和setter语法不能正确包装它。设置innerRadius时设置代码不调用的函数,而不是内部值。

有一个丑陋的解决方案,其中如果您放弃输入并使参数可选,它允许您同时执行这两个操作。所以我目前的解决方案是定义这样的包装器:

@JS('d3')
library d3;

import 'dart:js';
import "package:js/js.dart";


@JS("arc")
class Arc {
    external Arc();
    external innerRadius([num innerRadius]);
}

允许你这样称呼它:

Arc arc = new Arc()
    ..innerRadius(25);
num radius = arc.innerRadius();

这有效,但有一个缺点,我们失去了一些打字的价值,因为我无法输入强制将半径作为数字。也就是说,这同样有效:

Point<num> radius = arc.innerRadius();

直到运行时它才会爆炸。

所以这匹配它映射的函数并且它可以工作,但我真正想要的是能够使用类型进行操作,从而定义一个具有相同名称的函数,它们都可以返回相同的类型。

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你希望能够设置innerRadius(值)并获得innerRadius。为此我会做以下事情......

external Arc set innerRadius(num value);
external num get innerRadius;

以上几乎就是你所要求的,除了吸气剂将以下列方式使用...

num radius = arc.innerRadius;

答案 1 :(得分:0)

我们不再需要定义自己的JavaScript定义文件,因为Dart有一个从TypeScript文件中执行此操作的工具。 JS Facade Generatorofficial Dart Page about JS Interoperability。 有关在DefinitelyTyped project上使用此功能的更多信息。

感谢{{3}},几乎可以肯定有一个TypeScript文件允许你这样做。如果没有,请编写其中一个,它将帮助Dart和TypeScript社区。