将从 javascript API 返回的 javascript 对象转换为飞镖 class

converting a javascript object returned from a javascript API to a dart class

我正在尝试使用 https://pub.dartlang.org/packages/js.

中的 js 包创建 auth0 javascript API 的 dart 实现

所以我在 index.html 中加载 https://cdn.auth0.com/js/lock/10.0.0/lock.min.js 并创建了以下 auth0lock dart class:

@JS()
library auth0lock;

import 'package:js/js.dart';

@JS('Auth0Lock') 
class Auth0LockJS {
  external factory Auth0LockJS(String token, String domain, Object options);
  external on(String event, Function func);
  external show();
}

class Auth0Lock {
  Auth0LockJS auth0;
  Auth0Lock(String token, String domain, Object options) {
    this.auth0 = new Auth0LockJS(token,domain,options);
  }
  on(String event, Function func) {
    this.auth0.on(event,allowInterop(func));
  }
  show() {
    this.auth0.show();
  }
}

@anonymous
@JS()
class AuthResult {
 external factory AuthResult({
  String accessToken,
  String idToken,
  String idTokenPayload,
  String state
});
  external String get accessToken;
  external set accessToken(String v);
  external String get idToken;
  external set idToken(String v);
  external Object get idTokenPayload;
  external set idTokenPayload(Object v);
  external String get state;
  external set state(String v);
}

我正在编写一个 angular2-dart 应用程序,因此我创建了一个身份验证服务,该服务使用我之前使用以下代码显示的 auth0lock.dart 文件:

@Injectable()
class Auth {
    Auth0Lock lock;

    authenticatedEvent(AuthResult authResult) {
      print(authResult);
    }

    Auth() {
        this.lock = new Auth0Lock(configObj.auth0.apiKey, configObj.auth0.domain,{});
        this.lock.on("authenticated", authenticatedEvent);
    }
    updateProfileName(data) {
      var profile = data['profile'] != null ? data['profile'] : data;
      print(profile['name']);
    }

    authenticated() {
      return false;
    }

    login() {
       this.lock.show();
    }
}

现在...一切正常!我在 auth_service.dart 文件中创建了一个名为 lock 的类型为 AuthLock 的变量。我的实例带有参数,运行 show() 函数,连接到 authenticated 事件并在身份验证完成时触发该函数。

我创建了一个 class AuthResult 但它忽略了它并且我从函数处理程序中得到一个 javascript 对象 return。

我使用 Intellij 编写代码并使用 dartium 执行。因此,当我在 auth_service.dart 文件的 print(authResult); 行上放置断点时,调试器显示 authResult 对象包含 2 个属性,JavaScript View 类型 Objectclass 类型 JSObjectimplJavascript View 包含此函数处理程序 return 编辑的所有属性。

如何将它转换为 dart 中的常规 class?显然我创建了 AuthResult class 错误,因为函数处理程序没有 return 这种类型。那我错过了什么?

谢谢!

更新

authenticatedEvent 函数中我尝试打印 authResult.values,它产生了一个错误,即 JSObjectImpl 类型的 class 没有那个函数。所以 return 对象的类型是 JSObjectImpl。奇怪的是,我不知道 JSObjectImpl 在哪里定义,所以我删除了 authResult 的变量类型,并尝试使用以下代码在目录中使用变量:

authenticatedEvent(authResult) {
  var a = authResult.accessToken;
  print(a);
}

这行得通。为什么我在 dart 中找不到 JSObjectImpl 类型?有什么快速方法可以将其转换为飞镖 class?

谢谢

也许您只需要从 AuthResult

中删除 @anonymous

一个简化但完整且相似的示例

index.html

<!doctype html>
<html>
  <head>
    <script>
      var Apple = function(type) {
        this.type = type;
        this.color = "red";
        this.getInfo2 = function() {
          return this.color + ' ' + this.type + ' apple';
        };
      };

      Apple.prototype.getInfo = function() {
        return this.color + ' ' + this.type + ' apple';
      };

      function callback(f) {
        console.log(f);
        f(new Apple('Golden Delicious'));
      }
    </script>
  </head>
  <body>
    <script type="application/dart" src="index.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>

index.dart

@JS()
library typed_callback.web;

import 'package:js/js.dart';

@JS()
class Apple {
  external String get type;
  external set type(String type);
  external String get color;
  external set color(String color);
  external String getInfo();
  external String getInfo2();
  external Apple(String type);
}

typedef void Callback(Apple a);

@JS('callback')
external void callback(Callback /* or just Function */ f);

f(Apple apple) {
  print(apple.getInfo());
  print(apple); // prints the stringified JS object [object Object]
}

main() async {
  callback(allowInterop(f));
}