Dart JS 库,如何传递回调函数
Dart JS Library, how to pass callback functions
我们正在尝试使用带有 https://pub.dartlang.org/packages/js. We've followed https://github.com/google/chartjs.dart/ 的 Dart 包装器包装 D3 (v4) 行生成器 class,但在传递函数时遇到问题。
我们的包装看起来像这样:
@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 示例,但它们都以相同的堆栈跟踪结束。正确的做法是什么?
事实证明函数被正确附加和调用,问题在于我定义了 x 方法只用一个变量 d 调用。
JavaScript 中大多数 D3 访问器函数都是这样定义的,您只关心当前正在修改的那条数据。然而D3总是传递三个变量,数据d,索引i,整个数据集data[=25] =]. JavaScript 不在乎函数不接受额外的参数,它只是用一个参数调用它。然而 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]]);
我们正在尝试使用带有 https://pub.dartlang.org/packages/js. We've followed https://github.com/google/chartjs.dart/ 的 Dart 包装器包装 D3 (v4) 行生成器 class,但在传递函数时遇到问题。
我们的包装看起来像这样:
@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 示例,但它们都以相同的堆栈跟踪结束。正确的做法是什么?
事实证明函数被正确附加和调用,问题在于我定义了 x 方法只用一个变量 d 调用。
JavaScript 中大多数 D3 访问器函数都是这样定义的,您只关心当前正在修改的那条数据。然而D3总是传递三个变量,数据d,索引i,整个数据集data[=25] =]. JavaScript 不在乎函数不接受额外的参数,它只是用一个参数调用它。然而 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]]);