首页 文章

Dart JS Library,如何传递回调函数

提问于
浏览
1

我们试图用带有https://pub.dartlang.org/packages/js的Dart包装器包装D3(v4)行生成器类 . 我们已经关注https://github.com/google/chartjs.dart/但是在通过函数时遇到了问题 .

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

@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值 . 我们尝试过使用:

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)

这似乎是在尝试将参数传递给某些东西时发生的:

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

VM3533的位置是:

(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示例,但它们都以相同的堆栈跟踪结束 . 这样做的正确方法是什么?

1 回答

  • 0

    所以事实证明函数被正确地附加和调用,问题在于我已经定义了仅用一个变量d调用的x方法 .

    这就是大多数D3访问器函数在JavaScript中定义的方式,您只关心当前正在修改的数据 . 但是,D3总是传递三个变量,即数据 d ,索引 i 和整个数据集 data . JavaScript没有't care that the function doesn' t采取额外的参数,它只用一个参数调用它 . 然而,Dart确实关心,并且会因为参数过载而无法应用该函数 . 这是VM3533中发生的异常 .

    抛出的异常是令人讨厌的模糊,没有调试JavaScript很难看到 .

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

    在这种情况下:

    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]]);
    

相关问题