Declaración de la colección Backbone en CoffeeScript

Estoy tratando de encontrar la forma correcta de declarar un modelo para una colección Backbone en CoffeeScript. Déjame demostrarte con un ejemplo:

class MyApp.Collections.Likes extends Backbone.Collection
  constructor: (@models, @options) ->
  model: MyApp.Models.Like

Cuando inicializo esta colección y creo un nuevo modelo, falla.

likes = new MyApp.Collections.Likes
like = new likes.model // same result for likes.model.new

TypeError: Result of expression 'likes.model' [undefined] is not an object.

En cuanto al JavaScript compilado, el modelo se define de la siguiente manera:

MyApp.Collections.Likes = (function() {
  __extends(Likes, Backbone.Collection);
  function Likes(models, options) {
    this.models = models;
    this.options = options;
  }
  Likes.prototype.model = MyApp.Models.Like; // <--
  return Likes;
})();

Podría definir el modelo de dos formas que funcionarán:


solución 1

class MyApp.Collections.Likes extends Backbone.Collection
  constructor: (@models, @options) ->
  model: -> MyApp.Models.Like // Notice the ->

Que lo compila para:

MyApp.Collections.Likes = (function() {
  __extends(Likes, Backbone.Collection);
  function Likes(models, options) {
    this.models = models;
    this.options = options;
  }
  Likes.prototype.model = function() { // <-- added to the prototype as a function
    return MyApp.Models.Like;
  }
  return Likes;
})();

solución 2

class MyApp.Collections.Likes extends Backbone.Collection
  constructor: (@models, @options) ->
  @model: MyApp.Models.Like // Notice the @

Que lo compila para:

MyApp.Collections.Likes = (function() {
  __extends(Likes, Backbone.Collection);
  function Likes(models, options) {
    this.models = models;
    this.options = options;
  }
  Likes.model = function() { // <-- not added to prototype
    return MyApp.Models.Like;
  }
  return Likes;
})();

Estoy bastante seguro solución 1 es la mejor solución. Sin embargo, muchos sitios que he visto con tutoriales lo definen sin el -> or @.

¿Estoy haciendo algo descaradamente mal?

No hay nada malo en el Like modelo, es bastante vainilla:

class MyApp.Models.Like extends Backbone.Model

preguntado el 27 de agosto de 11 a las 20:08

3 Respuestas

No puedo replicar tu error. Aquí está mi código:

class Like extends Backbone.Model

class Likes extends Backbone.Collection
    model: Like

likes = new Likes
like = new likes.model
console.log like instanceof Like  # true

¿Es posible que haya cometido un error tipográfico en alguna parte? En particular, es MyApp.Models.Like definido en el punto donde escribe model: MyApp.Models.Like? Los exámenes

console.log MyApp.Collections.Likes::model?

y

console.log MyApp.Collections.Likes::model is MyApp.Models.Like

ambos deberían darte true. Y si lo hacen, entonces new likes.model debe ser equivalente a new MyApp.Models.Like.

Respondido 28 ago 11, 00:08

¿Podría mostrarme su JavaScript compilado para el modelo y la colección? - Jey Balachandran

@Jey ¿Por qué no copiar y pegar el código en el cuadro Probar CoffeeScript en coffeescript.org? - Trevor Burnham

Arg, he estado escribiendo esta aplicación TDD y no me he molestado en verificar esto en un navegador. El problema en realidad estaba en mi configuración de Jasmine, que cargaba todos los archivos JavaScript compilados public/javascript/compiled/**/*.js. Esto no tiene en cuenta el orden de dependencia, lo que resultó en este error. Gracias por probar que lo que hice inicialmente funcionó en el navegador. - Jey Balachandran

Si está haciendo todo lo posible por TDD, es posible que desee utilizar puntada. Luego, puede probar en Node y concatenar todo para el navegador. Ejecuté mi código de prueba en Node, ya que es rápido de configurar (solo npm install backbone y luego poner Backbone = require 'backbone' en la parte superior de su archivo). - Trevor Burnham

¿Qué esperas que suceda cuando escribes?

like = likes.model.new

? Esa sintaxis funciona en Ruby, pero en CoffeeScript, simplemente asigna la new propiedad de likes.model a like. En este caso, eso va a ser undefined. Probar

like = new likes.model

en vez.

Respondido 28 ago 11, 00:08

Eso fue en realidad un error tipográfico de mi parte, solo estaba probando algo y olvidé volver a cambiarlo. He probado ambos new likes.model y likes.model.new. Mismo error. [Corrigiendo mi pregunta] - Jey Balachandran

Oye, sé que llego tarde a esta fiesta, pero quería agregar que cada vez que he visto este problema es porque los programadores olvidan que las clases en coffeescript son una abstracción con fugas y que sus declaraciones no se leen antes de la ejecución. en este caso es necesario definir el modelo antes el js compilado intenta agregarlo al prototipo de la Colección.

respondido 15 nov., 12:00

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.