4
votes

est-il possible d'utiliser paresseusement les bibliothèques JS avec Dart?

J'utilise chartjs (avec l'interface dart https://pub.dartlang.org/packages/ chartjs ) et en essayant de le rendre différé en injectant un dans la section head et en attendant son événement de chargement pour ensuite utiliser la lib .
Je reçois cette exception: impossible de lire la propriété 'Chart' non définie.

Cela ne se produit pas lorsque le script est dans la tête du html avant le dard.

Alors, est-il possible de charger une librairie JS après le chargement de Dart?


4 commentaires

J'ai une expérience pour charger js-library pendant l'initialisation du composant angulaire. github.com/alexd1971/angular_grecaptcha/blob/master/lib/ src / ‌… Dans le script ngOnInit, la balise est créée et ajoutée au DOM. Dans ngAfterViewInit en attente du script est chargé et le composant d'initialisation. Mais cela ne fonctionne malheureusement pas toujours. Par exemple ici: github.com/alexd1971/angular_flatpickr . Je n'ai pas encore découvert pourquoi.


Cela semble être un problème avec l'attente de la fin du chargement. J'ai utilisé cette approche il y a quelque temps et cela a fonctionné pour moi (pas Chartjs cependant)


J'ai essayé de charger le script sur main.dart pour m'assurer qu'il est chargé, mais cela ne fonctionnait toujours pas


Le problème est que certains fichiers JS ne peuvent pas être ajoutés au dom après le chargement de Dart. Je viens de le tester en ajoutant simplement le après le script main.dart.js et il a renvoyé cette erreur: Erreur: module define () anonyme incompatible: fonction () {var définir, module, exportations;


3 Réponses :


0
votes

Vous pouvez essayer la syntaxe différée en tant que :

import 'package:chartjs/chartjs.dart' deferred as chartjs;

void main() {
    chartjs.loadLibrary().then(() { ... });
}


1 commentaires

mais cela rend l'interface différée, pas le script js réel, non?



2
votes

c'est un problème dans DDC. Il ajoute require.js au HTML et entre en conflit avec d'autres bibliothèques.
https://github.com/dart-lang/sdk/issues/33979

La solution que j'ai trouvée est de supprimer manuellement la section d'en-tête qui utilise requirejs de la bibliothèque tierce que vous souhaitez utiliser.

Par exemple, prenez chartjs: https://cdn.jsdelivr.net/npm/chart.js@2.8.0/dist/Chart.js

Vous supprimez ces deux lignes:

class ClientUtils {
    static final _scriptFetched = <String, Future<bool>>{};

    static ScriptElement _scr(String url) => new ScriptElement()
      ..async = true
      ..type = 'text/javascript'
      ..src = url;

    static Future<bool> fetchScript(String url,
            {String contextCheck}) async {
        bool shouldCheck = contextCheck?.isNotEmpty == true;

        hasContext() => js.context.hasProperty(contextCheck) &&
                    js.context[contextCheck] != null;

        if (shouldCheck && hasContext())
            return true;

        if (!_scriptFetched.containsKey(url)) {
            Completer<bool> c = new Completer<bool>();

            if (!shouldCheck) {
                ScriptElement s = _scr(url)
                    ..onLoad.forEach((Event e) {
                        c.complete(true);
                    });

                document.body.children.add(s);
            } else {
                Timer.periodic(Duration(milliseconds: 300), (t) {
                    if (hasContext()) {
                        t.cancel();
                    }
                    c.complete(true);
                });

                document.body.children.add(_scr(url));
            }

            _scriptFetched[url] = c.future;
        }
        return _scriptFetched[url];
    }
}

Ensuite, le fichier peut être ajouté paresseusement au DOM sans conflits.

Voici mon code pour récupérer paresseusement les scripts:

typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(function() { try { return require('moment'); } catch(e) { } }()) :
typeof define === 'function' && define.amd ? define(['require'], function(require) { return factory(function() { try { return require('moment'); } catch(e) { } }()); }) :


0 commentaires

2
votes

a trouvé un meilleur moyen!

supprimons la variable define après le chargement des fléchettes, puis toute bibliothèque tierce fonctionne lorsqu'elle est ajoutée async: D

ajoutez ceci à votre main ():

    <script type="text/javascript">
      window.fixRequireJs = function()
      {
        console.log('define is ', typeof define);
        if (typeof define == 'function') {
          console.log('removing define...');
          delete define;
          window.define = null;
        }
      }
    </script>

et dans votre index.html:

import 'dart:js';

void main() {
  context.callMethod('fixRequireJs');
}


0 commentaires