I'm making chaining selects with backbone.js by this article http://blog.shinetech.com/2011/07/25/cascading-select-boxes-with-backbone-js/, but got errors, when extending classes.
So, i have LocationsView class:
class Blog.Views.LocationsView extends Backbone.View
events:
"change": "changeSelected"
CountriesView class:
class Blog.Views.CountriesView extends Blog.Views.LocationsView
setSelectedId: (countryId) ->
CitiesView class:
class Blog.Views.CitiesView extends Blog.Views.LocationsView
setSelectedId: (cityId) ->
But when coffeescript code compiled to javascript my double extended classes looks like:
(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);
And i got error:
Uncaught TypeError: Cannot read property 'prototype' of undefined cities_view.js:5
So, where the problem is and how to fix it?
Since you are using ROR, is it correct to say that you are using 3.1 with the asset pipeline? If you are not using 3.1, then this info might still be useful, depending on how you are doing things.
The asset pipeline in 3.1 will bring your js files in alphabetical order when the files are within the same folder.
Because of that, cities_view.js will be executed before locations_view.js. Then, when CitiesView
tries to define itself, LocationsView
doesn't exist yet. (But this confuses me a bit because shouldn't you be using .coffee files instead of .js files?)
You will have to muck with the order of the files in the asset pipeline (controllable via comments) in order to get the correct file executed... or change the names.
In other words, you can tell Sprockets (the thing in RoR which manages your asset pipeline) to require the other file first.
At the top of your cities_view.coffee
file, you can add the following line:
##= require ./locations_view
Good luck
As @brian Genisio says, Its the alphabetical ordering of file loading in ROR's asset pipeline that's the issue.
I've found it useful to put all models that inherit from others in a sub-directory. This way, ROR loads all files in the parent directory first, before loading files in the sub-directory. It also appears more logical to the reader.
e.g. vehicle.js
and car.js
(where car extends vehicle) in the same directory wouldn't work, as car.js
is loaded and run before vehicle.js
, and isn't able to inherit from it.
Putting car.js
in a sub directory (e.g. vehicle_models/car.js
) would then work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With