2012-08-16 11 views
39

Ich verwende Requirejs, um das JavaScript in unserer Web-App zu laden. Das Problem ist, dass ich ein undefined Objekt bekomme, das an ein Modul übergeben wird, das, wenn es in anderen Modulen verwendet wird, vollkommen instanziiert wird.Undefiniertes Objekt, das über Requirejs übergeben wird

OK, hier ist das Setup. Meine main.js Datei, die läuft beim Start requirejs:

require.config({ 
    baseUrl: "/scripts", 
    paths: { 
     demographics: "Demographics/demographics", 
     complaints: "Complaints/complaints", 
    } 
}); 

require(["templates", "demographics", "complaints", "crossDomain"], function (templates, demographics, complaints) { 
    "use strict"; 

    console.log("0"); 
    console.log(demographics === undefined); 

    demographics.View.display(); 
}); 

Viele der Config nur auf die Core-Dateien in diesem Problem gestrippt wurde.

Hier Demographics.js:

define(["ko", "templates", "complaints", "globals", "underscore"], function (ko, templates, complaints, globals) { 

    // Stuff removed. 
    return { 
     View: view 
    }; 
}); 

und Complaints.js

define([ 
    "demographics", 
    "ko", 
    "templates", 
    "complaints", 
    "visualeffects", 
    "globals", 
    "webservice", 
    "underscore", 
    "typewatcher", 
    "imagesloaded"], 
    function (demographics, ko, templates, complaints, visualeffects, globals, webservice) { 
     "use strict"; 


     console.log("1"); 
     console.log(demographics === undefined); 
    return { 
     View: view 
    }; 
}); 

Das Problem ist dies - in Complaints.js der demographics Parameter über die define Config übergeben undefined ist. Das Abmelden der Konsole sagt mir, dass "demographics === undefined" true ist.

Wenn jedoch die main.js-Datei ausgeführt wird, ist der Parameter demographics, der an sie übergeben wird, nicht undefiniert, es handelt sich wie erwartet um ein instanziiertes Objekt.

Jetzt bin ich fest, seit ich nicht sehen kann, warum in complaints.js diese demografische Variablen undefiniert ist. Kann jemand bitte was ich vermisse?

Antwort

56

Sie haben eine zirkuläre Abhängigkeit. Das demographics Modul ist abhängig von complaints und complaints hängt von demographics ab. Gemäß der documentation:

Wenn Sie eine zirkuläre Abhängigkeit (eine Bedarfs b und b muss a) definieren, dann in diesem Fall, wenn das Modul Funktion b genannt wird, wird es einen nicht definierten Wert für eine bekommen.

Die Lösung, wenn Sie die zirkuläre Abhängigkeit nicht entfernen können, ist asynchron ein auf Nachfrage innerhalb des anderen der beiden Module erfordern (etwa, wenn die Ansicht instanziiert wird, statt, wenn das Modul, das die Ansicht definiert ist hingerichtet). Auch hier deckt das docs dieses Thema ziemlich gut ab.

+0

Ahh, genau das, was ich vermutete, aber wirklich nicht gedacht, dass das passieren könnte (Ich bin ein echter Neuling mit diesem AMD/requires Zeug :) Mein Plan der Aktion ist ein anderes Modul zu erstellen, das den Code für beide hostet die Demographie und die Beschwerden. Das bedeutet, dass dieses neue Modul verwendet wird, um den Code aus den beiden anderen Dateien aufzurufen. Danke für die Bestätigung meiner Gedanken. Werde es versuchen, wenn ich die Zeit habe. –

26

Ein anderer Fall ist, wenn Sie versehentlich require anstelle von bei der Definition eines Moduls eingeben, brauchte ich einige Zeit, um dies zu bemerken.

11

Ich hatte ein ähnliches Problem. In meinem Fall, wenn ein Modul, hatte ich geschrieben:

define('some_dependency', ... 

statt

define(['some_dependency'], ... 
4

Ein weiterer möglicher Grund ist die Umsetzung des Moduls Schnittstelle (AMD, Commonjs), aber vergessen, etwas zurück. Ich habe das gerade getan.

0

Ein anderer möglicher Grund, der im Nachhinein offensichtlich aussehen kann, ist ein Fehler in Ihrem Modulcode. In meinem Fall habe ich versucht, ein Attribut von einer undefinierten Variable zu bekommen. Der Fehler wird in der Konsole protokolliert, aber aus irgendeinem Grund habe ich ihn nicht gesehen/verwechselte ihn für den undefinierten Modulfehler.

-1

begegnete ich nur einen weiteren Grund:

define(function() { 
    return {}; 
}()); // <-- notice the '()' typo. 

Dieses „Tippfehler“ verursacht keine JS Fehler für diese ein und kann es verwirrend machen vor allem mit vielen potentiellen Kreis Abhängigkeiten in einer komplizierten Anwendung herauszufinden.

Der Grund, natürlich, ist der "Tippfehler" ist gültig JS, die einfach die Funktion, die Sie definieren, so übergibt ihr Ergebnis an define() anstatt die Funktion wie vorgesehen.

Verwandte Themen