2016-09-05 2 views
0

.NET-Entwickler ziemlich neu in modernen, clientseitigen Webanwendungen. Ich entwickle eine Angular2 Charting-Anwendung mit Chart.js. Module werden mit SystemJS geladen.Modul lädt nicht in der richtigen Reihenfolge

Das ist mein systemjs.config.js:

(function(global) 
{ 
    System.config(
    { 
     map: 
     { 
      "es6-shim": "node_modules/es6-shim", 
      "rxjs": "node_modules/rxjs", 
      "zone": "node_modules", 
      "reflect": "node_modules/reflect-metadata", 
      "jquery": "node_modules/jquery/dist", 
      "@angular": "node_modules/@angular", 
      "@angular/platform-browser": "node_modules/@angular/platform-browser", 
      "@angular/platform-browser-dynamic": "node_modules/@angular/platform-browser-dynamic", 
      "bootstrap": "node_modules/bootstrap", 
      "jasny-bootstrap": "bower_components/jasny-bootstrap", 
      "chart.js": "node_modules/chart.js", 
      "app_component": "app_modules" 
     }, 
     packages: 
     { 
      "es6-shim": { main: "es6-shim.min.js" }, 
      "rxjs": { main: "bundles/Rx.umd.min.js" }, 
      "zone": { main: "zone.js/dist/zone.min.js" }, 
      "reflect": { main: "Reflect.js" }, 
      "jquery": { main: "jquery.min.js" }, 
      "@angular/core": { main: "bundles/core.umd.min.js" }, 
      "@angular/common": { main: "bundles/common.umd.min.js" }, 
      "@angular/compiler": { main: "bundles/compiler.umd.min.js" }, 
      "@angular/router": { main: "bundles/router.umd.min.js" }, 
      "@angular/http": { main: "bundles/http.umd.min.js" }, 
      "@angular/platform-browser": { main: "bundles/platform-browser.umd.min.js" }, 
      "@angular/platform-browser-dynamic": { main: "bundles/platform-browser-dynamic.umd.min.js" }, 
      "bootstrap": { main: "dist/js/bootstrap.min.js" }, 
      "jasny-bootstrap": { main: "dist/js/jasny-bootstrap.min.js" }, 
      "chart.js": { main: "dist/Chart.bundle.min.js" }, 
      "app_component": { main: "init.js" } 
     }, 
     meta: 
     { 
      "bootstrap": { deps: [ "jquery" ] }, 
      "jasny-bootstrap": { deps: [ "bootstrap" ] } 
     } 
    }); 

})(this); 

einige erforderliche Komponenten geladen werden, bevor das Winkelmodul wie diese initialisierte (Hauptseite, index.html):

<script src="node_modules/systemjs/dist/system.src.js"></script> 
<script src="systemjs.config.js"></script> 
<script> 

    var load = function(packageName) 
    { 
     return System.import(packageName) 
      .then(function() 
      { 
       console.log(`Package "${ packageName }" loaded successfully.`); 
      }) 
      .catch(function(error) 
      { 
       console.error(`Package "${ packageName }" could not be loaded.`, error); 
      }); 
    } 

    load("es6-shim") 
     .then(load("reflect")) 
     .then(load("zone")) 
     .then(load("jquery")) 
     .then(load("bootstrap")) 
     .then(load("jasny-bootstrap")) 
     .then(load("chart.js")) 
     .then(load("ovafloweb")) 
     .catch(function(error) 
     { 
      console.log("Could not load one or more of the prerequisite components to launch the application.", error) 
     }); 

</script> 

Dies erzeugt die folgende Ausgabe in der Konsole:

Also System.import() gibt ein Versprechen, nicht wahr? Und so funktioniert ein Versprechen then() und catch() Funktionen, richtig? Wenn Sie die then() Funktion aufrufen, wird der vorherige Anruf beendet, bevor Sie fortfahren, richtig? Nach der Konsolenausgabe wird Jasny-Boostrap vor bootstrap geladen, die vor jquery geladen wird, und so beide nicht laden können. Noch verwirrender ist, dass die Ladereihenfolge inkonsistent ist; manchmal sieht es wie folgt aus:

Package "es6-shim" loaded successfully. 
Package "reflect" loaded successfully. 
Package "zone" loaded successfully. 
Package "jasny-bootstrap" could not be loaded. Error: (SystemJS) Jasny Bootstrap's JavaScript requires jQuery(…)(anonymous function) 
Package "jquery" loaded successfully. 
Package "bootstrap" loaded successfully. 
Package "chart.js" loaded successfully. 
Package "ovafloweb" loaded successfully. 

Und manchmal sieht es wie folgt aus:

Package "es6-shim" loaded successfully. 
Package "reflect" loaded successfully. 
Package "zone" loaded successfully. 
Package "jquery" loaded successfully. 
Package "bootstrap" loaded successfully. 
Package "jasny-bootstrap" loaded successfully. 
Package "chart.js" loaded successfully. 
Package "ovafloweb" loaded successfully. 

ich googeln um und fand ein paar Beiträge was darauf hindeutet, dass die meta.package.deps Eigenschaft kann verwendet werden SystemJS zu sagen, was für ein Modul hängt davon ab und sicherzustellen, dass es zuerst lädt, aber das hat bei mir nicht funktioniert.

Alternativ könnte ich lade immer jquery mit einem <script> Tag in index.html, aber ich würde es vorziehen, diejenigen, auf ein Minimum zu halten - ich bin schon Sheets mit <style> Tags geladen, die ich Ich mag es nicht besonders, aber ich konnte keine bessere Lösung finden als webpack, die ich bis jetzt für mein Leben nicht herausfinden konnte. Noch.

Offensichtlich vermisse ich etwas, aber ich habe keine Ahnung, was es ist. Jede Eingabe wird sehr geschätzt.

Antwort

1

Diese

load("es6-shim") 
    .then(load("reflect")) 

tut nicht das, was Sie denken, es tut.

wartet auf seine this Argument, load("es6-shim"), zu vervollständigen, dann ruft eine Funktion, die Sie daran übergeben. Aber Sie übergeben keine Funktion, Sie geben ein Versprechen, das von load zurückgegeben wird, und Ihre load ruft sofort System.import auf, ohne auf irgendetwas zu warten.

Versuchen

load("es6-shim").then(function() { 
    return load("reflect"); 
}).then(function() { 
    return load(....); 
}).then(function() { 
    ... 

Oder Sie können den Code halten, die load die gleichen Anrufe, aber load umschreiben eine Funktion zurück:

var load = function(packageName) 
{ 
    return function() { 
     return System.import(packageName) 
      .then(function() 
      { 
       console.log(`Package "${ packageName }" loaded successfully.`); 
      }) 
      .catch(function(error) 
      { 
       console.error(`Package "${ packageName }" could not be loaded.`, error); 
      }); 
    } 

} 
+0

Die erste Lösung gearbeitet. Der zweite beklagte sich über die "Last (...). Dann" keine Funktion, aber ich bin mir noch nicht 100% sicher, warum, da mir die beiden sehr ähnlich sind. Vielen Dank! – that0th3rGuy

+0

Entschuldigung, die zweite Lösung erfordert das Schreiben der allerersten Ladung als 'load (" es6-shim ")(). Dann (load (" ... ', weil load jetzt Funktion zurückgibt, kein Versprechen. Oder Sie können mit beginnen Just-Resolved-Versprechen wie folgt: 'Promise.resolve(). then (load (" module1 ")). then (load (...' – artem

Verwandte Themen