2012-02-13 15 views
21

Estoy usando Rails 3.1 con CoffeeScript y me he encontrado con un problema. ¿Cómo invoco una función de un archivo .js.erb que se encuentra en un archivo .js.coffee?Rieles - Llamando CoffeeScript desde JavaScript

Diga la función en .js.coffee es la siguiente:

myName = -> "Bob" 

Me gustaría pensar que sólo podía llamarlo como cualquier función js regular, tales como:

var theName = myName(); 

Pero eso no' parece que funciona ¿Algunas ideas?

o es posible usar coffeescript en mi archivo .js.erb para hacer que todo sea igual?

+2

Realmente debería aceptar la respuesta de Flambino. ¡Es genial! –

Respuesta

54

La razón por la que no se puede llamar a la función CoffeeScript directamente, es que CoffeeScript está envuelto en una función invocada inmediatamente cuando se compila. Esto se hace para evitar que su código contamine el espacio de nombres global.

Esto generalmente es una buena idea ™, pero por supuesto puede evitarlo cuando lo necesite. Si desea una función u otra variable que sean accesibles todas partes (es decir, el alcance mundial), se puede decir simplemente

window.myName = -> "Bob" 

De esta manera, se añade la función directamente en el ámbito global y se le puede llamar desde en cualquier lugar como window.myName() (o simplemente como myName() a menos que la función esté sombreada por una local).

Sin embargo, para mantener el espacio de nombres global lo más limpio posible, lo mejor es definir un espacio de nombres por sí mismo (como jQuery hace, poniendo todo lo en el objeto $). Por ejemplo, en el primer archivo CoffeeScript o JavaScript (es decir, el primer archivo que se cargue), se puede hacer algo como esto

window.myNamespace = {}; 

Entonces, cada vez que desee algo para estar disponible en otros lugares, lo puedes añadir a esa espacio de nombres:

window.myNamespace.myName = -> "Bob" 

Y entonces se le puede llamar desde cualquier lugar, utilizando window.myNamespace.myName() o simplemente myNamespace.myName().

Alternativamente, se puede utilizar de CoffeeScript "asignar si es indefinido o nula" operador en la parte superior de todos sus archivos:

window.myNamespace ?= {} # create myNamespace if it doesn't already exist 

Sea cual sea el archivo se evaluó por primera vez va a crear el window.myNamespace objeto que falta. El código posterior solo verá que ya existe y omitirá la asignación. El punto es que siempre estará disponible, independientemente de la orden de evaluación.

Edit: Made myNamespace lower-camelcase puesto que es básicamente una variable; no un constructor/clase

Adición: Puede evitar la envoltura función mediante el modificador de línea de comandos -b/--bare, pero como se mencionó la envoltura es una buena cosa.

+0

Impresionante. Muchas gracias por la gran respuesta. Tengo ganas de probarlo esta noche. – Brad

+2

Fantástica respuesta fantástica – Arcolye

+0

Bondad, qué fantástica respuesta :) – simonmorley