2011-08-26 9 views
6

Soy nuevo en CoffeeScript, y parece que tengo problemas con la sintaxis para los métodos de llamada.Método de sintaxis de llamada en CoffeeScript

Aquí está el modelo de tarjeta:

class exports.Card extends Backbone.Model 
    defaults: 
    pip: '4' 
    suit: '♠' 
    color: 'b' 

    rows: -> 
    rows = 
     '4': [2, 0, 2] 
    rows[@pip] 

y la parte correspondiente de la plantilla:

<ul class="col cols-<%= @card.rows()[0] %>"> 

que me está dando el error Uncaught TypeError: Object #<Object> has no method 'rows'

En concreto, me estoy preguntando si Estoy usando una sintaxis incorrecta para el método de filas de la Tarjeta o si simplemente estoy entendiendo mal algo. ¡Gracias por adelantado!

Actualización:

Por alguna razón, @card.property siempre funciona bien, pero @card.any_method() nunca lo hace. Ya he pasado por alto esto mediante el uso de propiedades, pero me encantaría que alguien pudiera explicar este comportamiento. ¡Gracias de nuevo!

Actualización 2:

estoy usando http://brunchwithcoffee.com si se trata de una ayuda a nadie, y aquí está el archivo main.coffee para mostrar cómo se crea la instancia @card y se pasa a la vista.

window.app = {} 
app.routers = {} 
app.models = {} 
app.collections = {} 
app.views = {} 

Card = require('models/card_model').Card 
MainRouter = require('routers/main_router').MainRouter 
HomeView = require('views/home_view').HomeView 
CardView = require('views/card_view').CardView 

# app bootstrapping on document ready 
$(document).ready -> 
    app.initialize = -> 
    app.routers.main = new MainRouter() 
    app.views.home = new HomeView() 
    app.views.card = new CardView(model: new Card(color: 'r', suit: '♥', pip: '7')) 
    app.routers.main.navigate 'home', true if Backbone.history.getFragment() is '' 
    app.initialize() 
    Backbone.history.start() 
+1

¿Cómo se creó '@ card'? Como 'nuevas exportaciones.Card'? ¿Pasa la prueba '@card instanceof exports.Card'? –

+0

actualizado para mostrar cómo se está creando la tarjeta @ – mportiz08

+0

Consejo de estilo: Puede escribir '{Card} = requerir 'modelos/modelo_cardio' en lugar de' Tarjeta = requerir (' modelos/modelo_cardio '). Tarjeta'. –

Respuesta

14

Su sintaxis de llamada de método es correcta. Las normas relevantes para CoffeeScript son:

  • paréntesis son opcionales para las llamadas de método invocado con argumentos es decir

    object.method 1,2 
    

    o

    object.method(1,2) 
    
  • paréntesis son requeridos para llamadas de método invocado sin argumentos es decir,

    object.method() 
    

Para ver cómo funciona esto intente ejecutar el siguiente código en la 'Prueba CoffeeScript' editor en el sitio CoffeeScript:

class A 
    method: -> 
    console.log "A" 

(new A()).method(); 

Debido a que su sintaxis de llamada método es correcto, parece probable que el problema es que la @card variable no es una instancia de las exportaciones. Clase de tarjeta.

+0

hm, estoy realmente confundido entonces - la tarjeta @ es definitivamente una instancia de la clase de la Tarjeta, ya que soy capaz de hacer de manera segura '<% = @ card.pip%>' una de las líneas anteriores en la vista – mportiz08

+0

tenías razón - @ card era en realidad el equivalente a toJSON() de lo que pensaba que era – mportiz08

1

El problema es que pip no es una propiedad de la instancia Card; es una propiedad de Card::defaults, por lo que Backbone lo convierte en un atributo de la instancia Card, no una propiedad .Se puede acceder al atributo pip con

card.get 'pip' 

o directamente como

card.attributes.pip 

La razón de esta diferencia es que, en JavaScript, no hay manera de controlar una propiedad de los cambios, que Backbone tiene que hacer para despachar eventos (Si modifica pip con card.set 'pip', entonces Backbone dispara un evento "change", por ejemplo.)

Por lo tanto, su código debería funcionar bien si acaba de cambiar la última línea del método rows:

rows: -> 
    rows = 
    '4': [2, 0, 2] 
    rows[@get 'pip'] 

(Nota:. getters/setters son compatibles con algunos entornos JS, lo que permitirá asignar card.pip = ... al artículo card.set 'pip', ... ver Juan de Resig en él here Backbone no utiliza este enfoque, ya que pretende ser compatible . Con todos los navegadores modernos-ish)

+0

gracias por la aclaración de las propiedades y los atributos, pero sigo recibiendo el error "no tiene método" al llamar a cualquier método en @ tarjeta – mportiz08

0

Finalmente lo descubrió - se me olvidó que la variable @card referencia en la plantilla no se originó a partir del archivo main.coffee - que en realidad se está convirtiendo en JSON en el CardView aquí:

cardTemplate = require('templates/card') 

class exports.CardView extends Backbone.View 
    tagName: 'div' 
    className: 'card' 

    render: -> 
    $(@el).html cardTemplate(card: @model.toJSON()) 
    @ 

ahora tiene sentido por qué sólo las variables estaban trabajando y no métodos - @card era en realidad una representación JSON de la instancia de modelo.

Gracias por todas las sugerencias/aclaraciones chicos - lo siento por el error tonto: P

Cuestiones relacionadas