Dart JS Library,如何传递回调函数 [英] Dart JS Library, how to pass callback functions

查看:314
本文介绍了Dart JS Library,如何传递回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正尝试使用带有 https://的Dart包装器封装D3(v4)行生成器类。 pub.dartlang.org/packages/js 。我们遵循 https://github.com/google/chartjs.dart/ ,但

We are trying to wrap the D3 (v4) line generator class with a Dart wrapper with https://pub.dartlang.org/packages/js. We've followed https://github.com/google/chartjs.dart/ but are having problems passing through functions.

我们的包装器看起来像这样:

Our wrapper looks like this:

@JS('d3')
library d3;

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


@JS('line')
class Line {
  external Line();
  external String call (List<List<num>> data);
  external Line x(Function func);
  external Line y(Function func);
}

我们目前设法使用:

Line line = new Line();
String path = line([[10, 20], [200, 250]]);

但是,我们想设置一个函数来访问x和y值。
我们尝试使用:

However we would like to set a function to access the x and y values. We've tried using:

Line line = new Line();
line.x(allowInterop((d) { return d[0]+10;}));
line([[10, 20], [200, 250]]);

这会产生堆栈跟踪:

JSFunction._apply (dart:js:1300)
#1      JSFunction.call (dart:js:1290)
#2      CardinalLine.path (package:dials/app_component.dart:42:16)
#3      _View_AppComponent2.detectChangesInternal (package:dials/app_component.template.dart:189:49)
#4      AppView.detectChanges (package:angular2/src/core/linker/view.dart:247:10)
#5      DebugAppView.detectChanges (package:angular2/src/core/linker/view.dart:367:26)
#6      AppView.detectContentChildrenChanges (package:angular2/src/core/linker/view.dart:264:31)
#7      _View_AppComponent0.detectChangesInternal (package:dials/app_component.template.dart:118:10)
#8      AppView.detectChanges (package:angular2/src/core/linker/view.dart:247:10)
#9      DebugAppView.detectChanges (package:angular2/src/core/linker/view.dart:367:26)
#10     AppView.detectViewChildrenChanges (package:angular2/src/core/linker/view.dart:270:28)
#11     AppView.detectChangesInternal (package:angular2/src/core/linker/view.dart:259:10)
#12     AppView.detectChanges (package:angular2/src/core/linker/view.dart:247:10)
#13     DebugAppView.detectChanges (package:angular2/src/core/linker/view.dart:367:26)
#14     ViewRef_.detectChanges (package:angular2/src/core/linker/view_ref.dart:123:16)
#15     ApplicationRef_.tick.<anonymous closure> (package:angular2/src/core/application_ref.dart:443:63)
#16     List.forEach (dart:core-patch/growable_array.dart:254)
#17     ApplicationRef_.tick (package:angular2/src/core/application_ref.dart:443:32)
#18     ApplicationRef_._loadComponent (package:angular2/src/core/application_ref.dart:414:10)
#19     ApplicationRef_.bootstrap.<anonymous closure> (package:angular2/src/core/application_ref.dart:401:12)
#20     ApplicationRef_.run.<anonymous closure> (package:angular2/src/core/application_ref.dart:366:26)

而它试图传递参数的东西:

This appears to occur while it is trying to pass the arguments to something:

ORIGINAL EXCEPTION: V8 Exception(anonymous function) @ VM3533:1
VM3533:1 ORIGINAL STACKTRACE:(anonymous function) @ VM3533:1



Where VM3533 is:

(function() {
    var func = this;
    return function() {
        return func(Array.prototype.slice.apply(arguments));
    }
    ;
}
)

传递的参数是:

[[MutationRecord], MutationObserver]

突变记录由以下组成:

0: MutationRecord
addedNodes: NodeList[0]
attributeName: "hidden"
attributeNamespace: null
nextSibling: null
oldValue: null
previousSibling: null
removedNodes: NodeList[0]
target: div
type: "attributes"
__proto__: MutationRecord
length: 1
__proto__: Array[0]

我们尝试了很多变体, chartjs示例,但它们都以相同的堆栈跟踪结束。正确的方法是什么?

We've tried lots of variations, including following the chartjs example, but they all end with the same stack-trace. What is the right way to do this?

推荐答案

因此,结果是函数被正确地附加和调用,问题在这个事实中,我已经定义了x方法被调用只有一个变量d。

So it turns out that the function was being properly attached and called, the problem lay in the fact that I had defined the x method to be called with only one variable d.

这是大多数D3访问函数在JavaScript中定义,你只关心关于当前正在修改的数据片。但是D3总是传递三个变量,数据 d ,索引 i 和整个数据集数据。 JavaScript不关心函数不接受额外的参数,它只是用一个参数调用它。但Dart 确实关心,并会抛出一个摆动的函数不能应用由于参数的重载。这是VM3533中发生的异常。

This is how most D3 accessor functions are defined in JavaScript, you only care about the piece of data currently being modified. However D3 always passes three variables, the piece of data d, the index i, and the entire dataset data. JavaScript doesn't care that the function doesn't take the extra arguments, it just calls it with the one argument. However Dart does care, and will throw a wobbly that the function can't be applied due to an overload of arguments. This was the exception happening in VM3533.

抛出的异常很讨厌,很难看到,而不调试JavaScript。

The exception thrown is annoyingly vague, and hard to see without debugging the JavaScript.

因此,正确的解决方案是确保在定义一个函数时,它将从JavaScript中调用它具有在此上下文中调用的参数的精确数量。

So the correct solution is to ensure when you define a function that will be called from JavaScript that it has the exact amount of arguments that it will be called with in this context.

在这种情况下:

Line line = new Line();
line.x(
    allowInterop(
        (List<num> d, num i, List<List<num>> data) {
            return d[0]+10;
        }
    )
);
return line([[10, 20], [30, 40]]);

这篇关于Dart JS Library,如何传递回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆