2011-11-02 16 views
18

Sto facendo concatenare selezioni con backbone.js da questo articolo http://blog.shinetech.com/2011/07/25/cascading-select-boxes-with-backbone-js/, ma ho ottenuto errori durante l'estensione delle classi.Backbone.js - Coffeescript estende

Così, ho classe LocationsView:

class Blog.Views.LocationsView extends Backbone.View 
    events: 
    "change": "changeSelected" 

classe CountriesView: classe

class Blog.Views.CountriesView extends Blog.Views.LocationsView 
    setSelectedId: (countryId) -> 

CitiesView:

class Blog.Views.CitiesView extends Blog.Views.LocationsView 
    setSelectedId: (cityId) -> 

Ma quando CoffeeScript codice compilato a JavaScript mie doppie classi estesi sguardi del tipo:

(function() { 
    var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { 
    for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } 
    function ctor() { this.constructor = child; } 
    ctor.prototype = parent.prototype; 
cities_view.js:5 Uncaught TypeError: Cannot read property 'prototype' of undefined 
    child.prototype = new ctor; 
    child.__super__ = parent.prototype; 
    return child; 
    }; 
    Blog.Views.CitiesView = (function() { 
    __extends(CitiesView, Blog.Views.LocationsView); 
    function CitiesView() { 
     CitiesView.__super__.constructor.apply(this, arguments); 
    } 
    CitiesView.prototype.setSelectedId = function(cityId) {}; 
    return CitiesView; 
    })(); 
}).call(this); 

ed ho ottenuto l'errore:

Uncaught TypeError: Cannot read property 'prototype' of undefined cities_view.js:5 

Allora, dove è il problema e come risolvere il problema?

+0

Potrebbe fornire la traccia completa dello stack? – thejh

risposta

35

Poiché si utilizza ROR, è corretto dire che si sta utilizzando 3.1 con la pipeline di asset? Se non si utilizza 3.1, queste informazioni potrebbero comunque essere utili, a seconda di come si stanno facendo le cose.

La pipeline di asset in 3.1 porterà i file js in ordine alfabetico quando i file si trovano nella stessa cartella.

Per questo motivo, city_view.js verrà eseguito prima di locations_view.js. Quindi, quando CitiesView prova a definirsi, LocationsView non esiste ancora. (Ma questo mi confonde un po 'perché non dovresti usare i file .coffee invece dei file .js?)

Dovrai muck con l'ordine dei file nella pipeline degli asset (controllabile tramite commenti) in ordine per ottenere il file corretto eseguito ... o cambiare i nomi.

In altre parole, è possibile indicare Pignoni (la cosa in RoR che gestisce la pipeline delle risorse) per richiedere prima l'altro file.

Nella parte superiore del file cities_view.coffee, è possibile aggiungere la seguente riga:

##= require ./locations_view 

Buona fortuna

+0

Perfetto. Era così. Grazie! –

+3

Sono passati anni ma tu stai ancora risparmiando il culo con questa risposta, evviva! –

3

Come @ Brian Genisio dice, il suo l'ordine alfabetico dei file di carico in cantiere asset ROR che è il problema.

Ho trovato utile mettere tutti i modelli che ereditano dagli altri in una sottodirectory. In questo modo, ROR carica prima tutti i file nella directory principale, prima di caricare i file nella sottodirectory. Appare anche più logico per il lettore.

ad es. vehicle.js e car.js (dove l'auto estende il veicolo) nella stessa directory non funzionerebbe, poiché car.js viene caricato ed eseguito prima dello vehicle.js e non è in grado di ereditarlo.

L'inserimento di car.js in una sottodirectory (ad esempio vehicle_models/car.js) funzionerebbe.