Исключение, когда javascript вызывает метод класса Dart

#javascript #dart-html

#язык JavaScript #dart-html

Вопрос:

Я хочу вызвать методы класса Dart из javascript в веб-проекте, но это работает только с помощью сервиса webdev, а не с помощью сборки webdev. Приведенный ниже пример проекта VSCode воспроизводит проблему.

js scriptCmds сначала получает дескриптор класса Dart QCmds, вызывая getClassHandle, который объявляется с помощью аннотированной функции @JS. Затем это используется двумя вызовами js методов класса QCmds. При использовании сервиса webdev все работает нормально, параметры вызова верны, а возвращаемые значения соответствуют ожиданиям.

Однако при запуске того же проекта после сборки с помощью webdev build возникает исключение:

 (index):23 Uncaught TypeError: qs.display is not a function  at scriptCmds ((index):23)  at HTMLInputElement.onclick ((index):14)  

Есть ли какая-либо документация по этой теме? Должно ли это поддерживаться с помощью сборки webdev?

У меня есть обходной путь, который включает создание аннотированной функции @JS для каждого метода, а затем вызов целевого метода с использованием параметра экземпляра класса, переданного из js. Однако я бы предпочел гораздо более чистую реализацию, вызвав методы непосредственно из js.

Весь код Dart находится в main.dart, построен и протестирован на:

Dart SDK 2.14.4 (стабильный) (Ср Окт 13 11:11:32 2021 0200) на «windows_x64»
VS Код 1.62.3 (настройка пользователя) ОС: Windows 10 (Windows_NT x64 10.0.19043)
Chrome 96.0.4664.45 (Официальная сборка) (64-разрядная версия)

 @JS() library testcmds;  import 'dart:core'; import 'package:js/js.dart';   @JS('getClassHandle') external set _getClassHandle(void Function() f);  /// /// The js script first calls getClassHandle to get a QCmds class handle /// QCmds getClassHandle() {  // create a QScripter object  var qcmds = QCmds();  return qcmds; }   /// /// main.dart /// /// In this example a js script (scriptCmds) obtains a Dart class handle  /// by calling 'getClassHandle' and then calling the class members /// 'display' and 'mult'. ///  /// If built by WEBDEV SERVE, this works just fine. ///  /// If built by WEBDEV BUILD, calling a Dart class member from js  /// throws an exception: /// (index):23 Uncaught TypeError: qs.display is not a function /// at scriptCmds ((index):23) /// at HTMLInputElement.onclick ((index):14) /// void main() {  _getClassHandle = allowInterop(getClassHandle); }  /// /// A sample class of simple methods to be called by a js script. The /// script first calls getClassHandle to get a class handle. /// class QCmds {   ///  /// display text   ///  void display(String text) async {  print('in QCmds.display, text=$text');  }    ///  /// multiply a number by 2  ///  int mult(int value) {  print('In QCmds.mult, value = 7');  return 2 * value;  } }  

Here is the html that includes the js script. Click on the ‘click me’ button to trigger the js scriptCmds. See the outputs on the Chrome developer tools console.

 lt;!DOCTYPE htmlgt; lt;htmlgt; lt;headgt;  lt;meta charset="utf-8"gt;  lt;meta http-equiv="X-UA-Compatible" content="IE=edge"gt;  lt;meta name="viewport" content="width=device-width, initial-scale=1.0"gt;  lt;meta name="scaffolded-by" content="https://github.com/dart-lang/sdk"gt;  lt;titlegt;testcmdslt;/titlegt;  lt;script defer src="main.dart.js"gt;lt;/scriptgt;  lt;stylegt;  html, body {  width: 100%;  height: 100%;  margin: 0;  padding: 0;  font-family: 'Roboto', sans-serif;  }   #trigger-div {  height: 100%;  display: flex;  justify-content: center;  align-items: center;  }   #trigger-round {  padding: 40px;  border-radius: 50%;  background-color: darksalmon;  }  lt;/stylegt; lt;/headgt;  lt;bodygt;  lt;div id='trigger-div'gt;  lt;div id='trigger-round'gt;  lt;input type="button" value="Click me" id="script_trigger" onclick="scriptCmds()"gt;lt;/inputgt;  lt;/divgt;  lt;/divgt;  lt;pgt;open developer tools console to see resultslt;/pgt;   lt;scriptgt;  function scriptCmds() {   // first get the class handle  var qs = getClassHandle();   // call the display command (as class member)  qs.display('some text');   // call the mult command (as class member)  var result = qs.mult(7);  console.log('result='   result);  }  lt;/scriptgt; lt;/bodygt; lt;/htmlgt;  

and pubspec.yaml:

 name: testcmds description: Testing javascript js calling a Dart function version: 1.0.0  environment:  sdk: 'gt;=2.14.4 lt;3.0.0'  dependencies:  http: ^0.13.3  dev_dependencies:  build_runner: ^2.1.2  build_web_compilers: ^3.2.1  js: ^0.6.3  lints: ^1.0.0