从 Dart 中的 JavaScript 对象获取任意 属性
Getting an arbitrary property from a JavaScript object in Dart
编辑:Here is a minimal project that illustrates my issue. 您可以通过将其提供给浏览器来查看所描述的错误:pub get
然后是 pub serve
(dartium)或 pub build --mode=debug
(其他浏览器).
如何通过 JsObjectImpl 从 Dart 访问任意 JavaScript 属性?我正在使用 ace.js 库和我从 typescript 接口改编的 Dart 互操作,我调用的方法 returns 是一个带有键值对的普通 javascript 对象。
Dart 给了我一个 JsObjectImpl,它不能转换为 Map 或 JsObject,它们都有 [] 访问器。令人困惑的是,它似乎继承自已弃用的 JSObject(请注意 's' 在后者中大写),它没有 [] 访问器,因此我无法获取数据。
一些错误信息:
尝试从 JsObjectImpl 转换为 JsObject 时:
ORIGINAL EXCEPTION: type 'JSObjectImpl' is not a subtype of type 'JsObject' of 'obj' where
JSObjectImpl is from dart:js
JsObject is from dart:js
。我在使用 Map
时也收到类似的消息。
查看调试器中的对象,我可以令人沮丧地在 JS 视图中看到 属性,但在 Dart 对象中看到 而不是 :
4: Object
就是我要的数据
好的,这很有趣,节日快乐 :)
Map
似乎不支持 package:js
的自动转换。所以有几件事:
感兴趣的朋友,我们可以使用浏览器原生的 Object.keys
:
@JS()
library example;
import 'package:js/js.dart';
/// A workaround to converting an object from JS to a Dart Map.
Map jsToMap(jsObject) {
return new Map.fromIterable(
_getKeysOfObject(jsObject),
value: (key) => getProperty(jsObject, key),
);
}
// Both of these interfaces exist to call `Object.keys` from Dart.
//
// But you don't use them directly. Just see `jsToMap`.
@JS('Object.keys')
external List<String> _getKeysOfObject(jsObject);
一旦我们有一个任意的 JavaScript 对象就调用它:
var properties = jsToMap(toy.getData());
print(properties);
我不得不修改@matanlurey 解决方案,使其适用于 dart 2.12 并且是递归的。
import 'dart:js';
/// A workaround to deep-converting an object from JS to a Dart Object.
Object jsToDart(jsObject) {
if (jsObject is JsArray || jsObject is Iterable) {
return jsObject.map(jsToDart).toList();
}
if (jsObject is JsObject) {
return Map.fromIterable(
getObjectKeys(jsObject),
value: (key) => jsToDart(jsObject[key]),
);
}
return jsObject;
}
List<String> getObjectKeys(JsObject object) => context['Object']
.callMethod('getOwnPropertyNames', [object])
.toList()
.cast<String>();
编辑:Here is a minimal project that illustrates my issue. 您可以通过将其提供给浏览器来查看所描述的错误:pub get
然后是 pub serve
(dartium)或 pub build --mode=debug
(其他浏览器).
如何通过 JsObjectImpl 从 Dart 访问任意 JavaScript 属性?我正在使用 ace.js 库和我从 typescript 接口改编的 Dart 互操作,我调用的方法 returns 是一个带有键值对的普通 javascript 对象。
Dart 给了我一个 JsObjectImpl,它不能转换为 Map 或 JsObject,它们都有 [] 访问器。令人困惑的是,它似乎继承自已弃用的 JSObject(请注意 's' 在后者中大写),它没有 [] 访问器,因此我无法获取数据。
一些错误信息:
尝试从 JsObjectImpl 转换为 JsObject 时:
ORIGINAL EXCEPTION: type 'JSObjectImpl' is not a subtype of type 'JsObject' of 'obj' where JSObjectImpl is from dart:js JsObject is from dart:js
。我在使用Map
时也收到类似的消息。查看调试器中的对象,我可以令人沮丧地在 JS 视图中看到 属性,但在 Dart 对象中看到 而不是 :
4: Object
就是我要的数据
好的,这很有趣,节日快乐 :)
Map
似乎不支持 package:js
的自动转换。所以有几件事:
感兴趣的朋友,我们可以使用浏览器原生的 Object.keys
:
@JS()
library example;
import 'package:js/js.dart';
/// A workaround to converting an object from JS to a Dart Map.
Map jsToMap(jsObject) {
return new Map.fromIterable(
_getKeysOfObject(jsObject),
value: (key) => getProperty(jsObject, key),
);
}
// Both of these interfaces exist to call `Object.keys` from Dart.
//
// But you don't use them directly. Just see `jsToMap`.
@JS('Object.keys')
external List<String> _getKeysOfObject(jsObject);
一旦我们有一个任意的 JavaScript 对象就调用它:
var properties = jsToMap(toy.getData());
print(properties);
我不得不修改@matanlurey 解决方案,使其适用于 dart 2.12 并且是递归的。
import 'dart:js';
/// A workaround to deep-converting an object from JS to a Dart Object.
Object jsToDart(jsObject) {
if (jsObject is JsArray || jsObject is Iterable) {
return jsObject.map(jsToDart).toList();
}
if (jsObject is JsObject) {
return Map.fromIterable(
getObjectKeys(jsObject),
value: (key) => jsToDart(jsObject[key]),
);
}
return jsObject;
}
List<String> getObjectKeys(JsObject object) => context['Object']
.callMethod('getOwnPropertyNames', [object])
.toList()
.cast<String>();