#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