2012-08-16 12 views
39

Estoy usando Requirejs para cargar el JavaScript en nuestra aplicación web. El problema es que estoy recibiendo un objeto undefined que se pasa a un módulo que, cuando se usa en otros módulos, se instancia perfectamente.Objeto indefinido que se pasa a través de Requirejs

Bien, aquí está la configuración. Mi archivo main.js cuales RequireJS se ejecuta en el arranque:

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

Gran parte de la configuración se ha despojado a sólo los archivos principales de este problema.

Aquí es Demographics.js:

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

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

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

El problema es el siguiente - en Complaints.js el parámetro demographics pasa a través de la configuración define es undefined. El cierre de sesión de la consola me dice que "demographics === undefined" es true.

Sin embargo, cuando se ejecuta el archivo main.js, el parámetro demográfico que se le pasa no está indefinido, es, como se esperaba, un objeto instanciado.

Ahora estoy atascado ya que no puedo ver por qué en complaints.js esa variable demográfica no está definida. ¿Alguien puede detectar lo que me estoy perdiendo por favor?

Respuesta

56

Tiene una dependencia circular. El módulo demographics depende de complaints y complaints depende de demographics. De acuerdo con la documentation:

Si se define una dependencia circular (un b necesidades y B necesita una), entonces en este caso cuando la función del módulo de b se llama, se obtendrá un valor indefinido para una.

La solución, si no se puede eliminar la dependencia circular, es exigir de forma asíncrona uno de los dos módulos dentro de la otra en la demanda (por ejemplo, cuando se crea una instancia de la vista en lugar de cuando el módulo que define la vista es ejecutado). De nuevo, el docs cubre este tema bastante bien.

+0

Ahh, exactamente lo que sospechaba, pero realmente no pensé que esto podría pasar (soy un novato real con estas cosas de AMD/requirejs :) Mi plan de acción es crear otro módulo que alojará el código para ambos los datos demográficos y las quejas. Eso significa que este nuevo módulo se usará para llamar al código de los otros dos archivos. Gracias por confirmar mis pensamientos. Lo probaré cuando tenga el tiempo. –

26

Otro caso es cuando accidentalmente mecanografía require en vez de define al definir un módulo, me tomó algo de tiempo darme cuenta de esto.

11

Tuve un problema similar. En mi caso, cuando se define un módulo, que había escrito:

define('some_dependency', ... 

en lugar de

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

Otra posible razón está implementando la interfaz del módulo (AMD, CommonJS), pero olvidar devolver nada. Solo hice eso.

0

Otra razón posible que puede parecer obvia en retrospectiva es un error en el código de su módulo. En mi caso, estaba tratando de obtener un atributo de una variable indefinida. El error se registra en la consola, pero por alguna razón no lo estaba viendo/confundiéndolo con el error del módulo indefinido.

-1

que acabamos de encontrar otra razón:

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

Este "error tipográfico" provoca ningún error JS para éste y puede hacer que sea confuso para averiguar especialmente en una aplicación complicada con muchas dependencias circulares potenciales.

La razón, por supuesto, es el "error tipográfico" es un JS válido que simplemente llama a la función que define pasando su resultado a define() en lugar de la función prevista.

Cuestiones relacionadas