Backbone.js — расширение Coffeescript

Я создаю цепочки выбора с помощью backbone.js по этой статье http://blog.shinetech.com/2011/07/25/cascading-select-boxes-with-backbone-js/, но получил ошибки при расширении классов.

Итак, у меня есть класс LocationsView:

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

Класс CountryView:

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

Класс CityView:

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

Но когда код coffeescript скомпилирован в javascript, мои двойные расширенные классы выглядят так:

(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);

И я получил ошибку:

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

Итак, в чем проблема и как ее исправить?


person BazZy    schedule 02.11.2011    source источник
comment
Не могли бы вы предоставить полную трассировку стека?   -  person thejh    schedule 02.11.2011


Ответы (2)


Поскольку вы используете ROR, правильно ли говорить, что вы используете 3.1 с конвейером активов? Если вы не используете 3.1, эта информация может быть полезна, в зависимости от того, как вы работаете.

Конвейер ресурсов в версии 3.1 будет размещать ваши js-файлы в алфавитном порядке, если файлы находятся в одной папке.

Из-за этого city_view.js будет выполняться раньше, чем location_view.js. Затем, когда CitiesView пытается определить себя, LocationsView еще не существует. (Но это меня немного смущает, потому что разве вы не должны использовать файлы .coffee вместо файлов .js?)

Вам придется возиться с порядком файлов в конвейере ресурсов (управляемым с помощью комментариев), чтобы выполнить правильный файл... или изменить имена.

Другими словами, вы можете указать Sprockets (вещь в RoR, которая управляет вашим конвейером ресурсов) сначала запрашивать другой файл.

В верхней части файла cities_view.coffee вы можете добавить следующую строку:

##= require ./locations_view

Удачи

person Brian Genisio    schedule 02.11.2011
comment
Идеально. Вот оно. Спасибо! - person Sam Soffes; 18.07.2012
comment
Прошли годы, но вы все еще спасаете задницы этим ответом, ура! - person Rob Fox; 11.10.2013

Как говорит @brian Genisio, проблема заключается в алфавитном порядке загрузки файлов в конвейере ресурсов ROR.

Я нашел полезным помещать все модели, которые наследуются от других, в подкаталог. Таким образом, ROR сначала загружает все файлы в родительском каталоге, а затем загружает файлы в подкаталог. Это также кажется более логичным читателю.

например vehicle.js и car.js (где автомобиль расширяет транспортное средство) в одном и том же каталоге не будут работать, так как car.js загружается и запускается до vehicle.js и не может наследоваться от него.

Помещение car.js в подкаталог (например, vehicle_models/car.js) будет работать.

person Tom Wilshere    schedule 05.01.2013