2012-02-13 14 views
21

Sto utilizzando Rails 3.1 con CoffeeScript e ho incontrato un inconveniente. Come posso chiamare una funzione da un file .js.erb che si trova in un file .js.coffee?Rails - Calling CoffeeScript da JavaScript

Di 'la funzione nel .js.coffee è la seguente:

myName = -> "Bob" 

penserei ho potuto solo chiamare come qualsiasi funzione js regolare, come:

var theName = myName(); 

ma che doesn' t sembra funzionare. Qualche idea?

oppure è possibile utilizzare il coffeescript nel mio file .js.erb per rendere tutto uguale?

+2

Dovresti davvero accettare la risposta di Flambino. È ottimo! –

risposta

54

Il motivo per cui non è possibile chiamare direttamente la funzione CoffeeScript è che CoffeeScript è stato incluso in una funzione richiamata immediatamente al momento della compilazione. Questo è fatto per mantenere il tuo codice dall'inquinamento dello spazio dei nomi globale.

Questa è generalmente una buona idea ™, ma ovviamente è possibile aggirarla quando è necessario. Se si desidera una funzione o altra variabile siano accessibili ovunque (cioè portata globale), si può semplicemente dire

window.myName = -> "Bob" 

In questo modo, la funzione viene aggiunto direttamente alla portata globale, e si può chiamare da ovunque come window.myName() (o semplicemente come myName() a meno che la funzione non sia ombreggiata da una locale).

Tuttavia, per mantenere il namespace globale più pulito possibile, è meglio definire uno spazio dei nomi di persona (come jQuery fa, mettendo tutto nell'oggetto $). Per esempio, nel primo file CoffeeScript o JavaScript (vale a dire il primo file da caricare), si può fare qualcosa di simile

window.myNamespace = {}; 

Poi, ogni volta che si desidera qualcosa di essere disponibili altrove, è possibile aggiungerlo a quello namespace:

window.myNamespace.myName = -> "Bob" 

e poi si può chiamare da qualsiasi luogo, utilizzando window.myNamespace.myName() o semplicemente myNamespace.myName().

In alternativa, è possibile utilizzare di CoffeeScript "assegnare se non definita o nulla" operatore in alto di tutti i file:

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

Qualunque sia il file viene valutata per prima sarà creare l'window.myNamespace oggetto mancante. Il codice successivo vedrà solo che esiste già e salta il compito. Il punto è che sarà sempre disponibile, indipendentemente dall'ordine di valutazione.

Modifica: Made myNamespace inferiore-camelcase poiché è fondamentalmente una variabile; Non un costruttore/classe

Addendum: si può evitare la funzione wrapper utilizzando l'opzione della riga di comando -b/--bare, ma come detto l'involucro è una buona cosa.

+0

Fantastico. Grazie mille per l'ottima risposta. Non vedo l'ora di provarlo questa sera. – Brad

+2

Fantastica risposta fantastica – Arcolye

+0

Bontà, che risposta fantastica :) – simonmorley