2012-08-16 11 views
39

Sto utilizzando Requirejs per caricare JavaScript nella nostra app Web. Il problema è che sto ottenendo un oggetto undefined passato a un modulo che, se usato in altri moduli, viene istanziato perfettamente.Oggetto non definito passato tramite Requirejs

OK, ecco il setup. Il mio file main.js che requirejs eseguito all'avvio:

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(); 
}); 

Un sacco di config è stato spogliato da solo i file principali di questo problema.

Ecco Demographics.js:

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

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

e 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 
    }; 
}); 

Il problema è questo - nel Complaints.js parametro demographics passato attraverso il define config è undefined. La disconnessione della console mi dice che "demographics === undefined" è true.

Tuttavia, quando il file main.js viene eseguito, il parametro demografico passato non è indefinito, è, come previsto, un oggetto istanziato.

Ora sono bloccato poiché non riesco a capire perché in complaints.js tale variabile demografica non è definita. Qualcuno può individuare quello che mi manca, per favore?

risposta

56

Si dispone di una dipendenza circolare. Il modulo demographics dipende da complaints e complaints dipende da demographics. Come per il documentation:

Se si definisce una dipendenza circolare (una necessità b & b ha bisogno di una), quindi in questo caso, quando la funzione del modulo di b si chiama, si otterrà un valore indefinito per una.

La soluzione, se non è possibile rimuovere la dipendenza circolare, vale a richiedere asincrono uno dei due moduli all'interno dall'altro su richiesta (ad esempio quando la visualizzazione viene creata un'istanza invece quando il modulo che definisce la vista è eseguito). Ancora una volta, lo docs copre abbastanza bene questo argomento.

+0

Ah, esattamente quello che sospettavo, ma davvero non pensavo che questo potesse accadere (sono un vero novizio con questa roba AMD/requirejs :) Il mio piano d'azione è creare un altro modulo che ospiterà il codice per entrambi i dati demografici e le lamentele. Ciò significa che questo nuovo modulo verrà utilizzato per chiamare il codice dagli altri due file. Grazie per aver confermato i miei pensieri. Farò un tentativo quando avrò il tempo. –

26

Un altro caso è quando si digita accidentalmente require anziché define quando si definisce un modulo, mi ci è voluto un po 'di tempo per notarlo.

11

Ho avuto un problema simile. Nel mio caso, quando si definisce un modulo, che avevo scritto:

define('some_dependency', ... 

invece di

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

Un'altra possibile ragione sta implementando l'interfaccia del modulo (AMD, CommonJS), ma dimenticando di restituire qualcosa. L'ho appena fatto.

0

Un altro possibile motivo che può sembrare ovvio in seguito è un errore nel codice del modulo. Nel mio caso, stavo cercando di ottenere un attributo da una variabile non definita. L'errore viene registrato nella console, ma per qualche motivo non lo vedevo/errando per l'errore del modulo non definito.

-1

Ho appena incontrato un altro motivo:

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

Questo "errore di battitura" non causa JS errori per questo e può rendere confuso per capire soprattutto in un'applicazione complessa con molti potenziali dipendenze circolari.

Il motivo, ovviamente, è che "typo" è JS valido che chiama semplicemente la funzione definita dall'utente, quindi passa il risultato a define() anziché la funzione come previsto.

Problemi correlati