Использовать библиотеку js во флаттере - PullRequest
1 голос
/ 18 февраля 2020

Мне нужен виджет с bpmn. js просмотр: https://github.com/bpmn-io/bpmn-js

Используется HtmlElementView:

    // ignore: undefined_prefixed_name
    ui.platformViewRegistry
        .registerViewFactory('bpmn_view', (int viewId) => element);

    return Column(
      children: <Widget>[
        Expanded(
            child: HtmlElementView(key: UniqueKey(), viewType: "bpmn_view")),
      ],
    );

С js:

    const html = '''
    <div id="canvas">canvas</div>
    <script>
      (function () {
        window.addEventListener('view_bpmn', function (e) {
           var bpmnJS = new BpmnJS({
               container: "#canvas"
           });

           bpmnJS.importXML(e.details);
         }, false);
      }());
    </script>
    ''';

    element.setInnerHtml(html,
        validator: NodeValidatorBuilder.common()..allowElement('script'));

enter image description here

Но я получаю ошибку при выполнении:

VM4761 bpmn-viewer.development.js:18864 Uncaught TypeError: Cannot read property 'appendChild' of null
    at Viewer.BaseViewer.attachTo (VM4761 bpmn-viewer.development.js:18864)
    at Viewer.BaseViewer._init (VM4761 bpmn-viewer.development.js:18911)
    at Viewer.BaseViewer (VM4761 bpmn-viewer.development.js:18454)
    at new Viewer (VM4761 bpmn-viewer.development.js:19082)
    at <anonymous>:3:25
    at main.dart:185
    at future.dart:316
    at internalCallback (isolate_helper.dart:50)

И я не могу установить селектор для Bpmn JS как :

 var bpmnJS = new BpmnJS({
               container: "document.querySelector('flt-platform-view').shadowRoot.querySelector('#canvas')";
           });

Как мне заставить это работать?

1 Ответ

0 голосов
/ 20 апреля 2020

Поскольку параметр Bpmn JS container принимает значение типа DOMElement, мы можем напрямую передать результат querySelector:

    _element = html.DivElement()
      ..id = 'canvas'
      ..append(html.ScriptElement()
        ..text = """
        const canvas = document.querySelector("flt-platform-view").shadowRoot.querySelector("#canvas");
        const viewer = new BpmnJS({ container: canvas });
        """);

    // ignore: undefined_prefixed_name
    ui.platformViewRegistry
        .registerViewFactory('bpmn-view', (int viewId) => _element);

Bpmn JS модуль должен быть присоединен к index. html Файл (в папке верхнего уровня web вашего проекта):

<!DOCTYPE html>
<head>
  <title>BpmnJS Demo</title>
  <script defer src="main.dart.js" type="application/javascript"></script>
  <script src="https://unpkg.com/bpmn-js@6.4.2/dist/bpmn-navigated-viewer.development.js"></script>
</head>
...

Полный код:

import 'dart:ui' as ui;
import 'package:universal_html/html.dart' as html;
import 'package:flutter/material.dart';

class BpmnDemo extends StatefulWidget {
  @override
  _BpmnDemoState createState() => _BpmnDemoState();
}

class _BpmnDemoState extends State<BpmnDemo> {
  html.DivElement _element;

  @override
  void initState() {
    super.initState();

    _element = html.DivElement()
      ..id = 'canvas'
      ..append(html.ScriptElement()
        ..text = """
        const canvas = document.querySelector("flt-platform-view").shadowRoot.querySelector("#canvas");
        const viewer = new BpmnJS({ container: canvas });
        const uri = "https://cdn.staticaly.com/gh/bpmn-io/bpmn-js-examples/dfceecba/url-viewer/resources/pizza-collaboration.bpmn";
        fetch(uri).then(res => res.text().then(xml => viewer.importXML(xml)));
        """);

    // ignore: undefined_prefixed_name
    ui.platformViewRegistry
        .registerViewFactory('bpmn-view', (int viewId) => _element);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
          child: HtmlElementView(key: UniqueKey(), viewType: "bpmn-view")),
    );
  }
}

...