2016-08-18 2 views
1

Я определил D3 Dart JS Interop, который я использую, чтобы установить значения на объектах D3 и называть их, что хорошо работает. К сожалению, D3 использует ту же функцию как для сеттеров, так и для геттеров, и зависит от количества аргументов, чтобы разделить их.Dart JS Interop Перегрузка функции для ввода

Например, объект 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(); 
} 

Но он жалуется на имя уже будучи определены. Как определить dart-оболочку, чтобы я мог установить и вызвать значение, а также ввести его?

D3 определяет дугу, как это:

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; 
} 

Таким образом, геттер и сеттер синтаксис не обернуть его должным образом. Поскольку параметр 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

We больше не нужно определять наши собственные файлы определения JavaScript, поскольку у Dart есть инструмент для этого из файлов TypeScript. JS Facade Generator. Дополнительную информацию об использовании этого на official Dart Page about JS Interoperability.

Благодаря DefinitelyTyped project почти наверняка есть файл TypeScript, который позволит вам это сделать. Если нет, напишите один из них, это поможет как сообществам Dart, так и TypeScript.

1

Если я правильно понимаю ваш вопрос, вы хотите установить innerRadius (значение) и получить innerRadius. Для этого я хотел бы сделать следующее ...

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

выше будет делать почти точно, что вы спрашиваете, для геттера будет использоваться следующим образом, за исключением ...

num radius = arc.innerRadius; 
+0

Я пробовал это, но он не работает из-за реализации D3. Я обновил вопрос, почему это не работает. Спасибо за предложение. :) –

Смежные вопросы