我已经定义了一个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();
直到运行时它才会爆炸。
所以这匹配它映射的函数并且它可以工作,但我真正想要的是能够使用类型进行操作,从而定义一个具有相同名称的函数,它们都可以返回相同的类型。
答案 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 Generator。official Dart Page about JS Interoperability。 有关在DefinitelyTyped project上使用此功能的更多信息。
感谢{{3}},几乎可以肯定有一个TypeScript文件允许你这样做。如果没有,请编写其中一个,它将帮助Dart和TypeScript社区。 p>