2012-06-26 52 views
2

我有以下代碼塊。它完美的作品。Backbone.js路由器實例在某種程度上是無效的

<div id="restaurant_locations"></div> 

<script type="text/javascript"> 
    $(function() { 
    window.router = new Lunchhub.Routers.RestaurantLocationsRouter({restaurantLocations: <%= @restaurant_locations.to_json.html_safe -%>}); 
    var Foo = Backbone.Router.extend({routes: {"foo":"bar"}}); 
    r = new Foo(); 
    Backbone.history.start(); 
    }); 
</script> 

然而,這不起作用:

<div id="restaurant_locations"></div> 

<script type="text/javascript"> 
    $(function() { 
    window.router = new Lunchhub.Routers.RestaurantLocationsRouter({restaurantLocations: <%= @restaurant_locations.to_json.html_safe -%>}); 
    // All I did was delete the two lines that used to be here 
    Backbone.history.start(); 
    }); 
</script> 

後者片斷給了我這個錯誤:

Uncaught TypeError: Cannot call method 'start' of undefined 

所以我Foo路由器實例觸發Backbone.history一個正確的初始化,就像你會期望一個路由器實例做,但我的Lunchhub.Routers.RestaurantLocationsRouter實例不。

下面是我的CoffeeScript路由器定義(由backbone-rails寶石自動生成):

class Lunchhub.Routers.RestaurantLocationsRouter extends Backbone.Router 
    initialize: (options) -> 
    @restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection() 
    @restaurantLocations.reset options.restaurantLocations 

    routes: 
    "new"  : "newRestaurantLocation" 
    "index" : "index" 
    ":id/edit" : "edit" 
    ":id"  : "show" 
    ".*"  : "index" 

    newRestaurantLocation: -> 
    @view = new Lunchhub.Views.RestaurantLocations.NewView(collection: @restaurant_locations) 
    $("#restaurant_locations").html(@view.render().el) 

    index: -> 
    @view = new Lunchhub.Views.RestaurantLocations.IndexView(restaurant_locations: @restaurant_locations) 
    $("#restaurant_locations").html(@view.render().el) 

    show: (id) -> 
    restaurant_location = @restaurant_locations.get(id) 

    @view = new Lunchhub.Views.RestaurantLocations.ShowView(model: restaurant_location) 
    $("#restaurant_locations").html(@view.render().el) 

    edit: (id) -> 
    restaurant_location = @restaurant_locations.get(id) 

    @view = new Lunchhub.Views.RestaurantLocations.EditView(model: restaurant_location) 
    $("#restaurant_locations").html(@view.render().el) 

而這裏的編譯的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; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 

    Lunchhub.Routers.RestaurantLocationsRouter = (function(_super) { 

    __extends(RestaurantLocationsRouter, _super); 

    function RestaurantLocationsRouter() { 
     RestaurantLocationsRouter.__super__.constructor.apply(this, arguments); 
    } 

    RestaurantLocationsRouter.prototype.initialize = function(options) { 
     this.restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection(); 
     return this.restaurantLocations.reset(options.restaurantLocations); 
    }; 

    RestaurantLocationsRouter.prototype.routes = { 
     "new": "newRestaurantLocation", 
     "index": "index", 
     ":id/edit": "edit", 
     ":id": "show", 
     ".*": "index" 
    }; 

    RestaurantLocationsRouter.prototype.newRestaurantLocation = function() { 
     this.view = new Lunchhub.Views.RestaurantLocations.NewView({ 
     collection: this.restaurant_locations 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    RestaurantLocationsRouter.prototype.index = function() { 
     this.view = new Lunchhub.Views.RestaurantLocations.IndexView({ 
     restaurant_locations: this.restaurant_locations 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    RestaurantLocationsRouter.prototype.show = function(id) { 
     var restaurant_location; 
     restaurant_location = this.restaurant_locations.get(id); 
     this.view = new Lunchhub.Views.RestaurantLocations.ShowView({ 
     model: restaurant_location 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    RestaurantLocationsRouter.prototype.edit = function(id) { 
     var restaurant_location; 
     restaurant_location = this.restaurant_locations.get(id); 
     this.view = new Lunchhub.Views.RestaurantLocations.EditView({ 
     model: restaurant_location 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    return RestaurantLocationsRouter; 

    })(Backbone.Router); 

}).call(this); 

可能是錯誤怎麼回事?

編輯:我已經想出了部分問題。在CoffeeScript中,它在一些應該使用restaurantLocations的地方使用restaurant_locations。我現在遇到一個奇怪的問題,但可能更容易:當我將編譯的JavaScript直接複製並粘貼到<script>區域時,就在window.router =指定之前,一切正常。但是,當我嘗試使用編譯後的JS作爲外部文件(並且我知道它被包含在內部時 - 我檢查過),我得到了相同的Cannot call method 'start' of undefined錯誤。

這是我更新的CoffeeScript:

class Lunchhub.Routers.RestaurantLocationsRouter extends Backbone.Router 
    initialize: (options) -> 
    @restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection() 
    @restaurantLocations.reset options.restaurantLocations 

    routes: 
    "new"  : "newRestaurantLocation" 
    "index" : "index" 
    ":id/edit" : "edit" 
    ":id"  : "show" 
    ".*"  : "index" 

    newRestaurantLocation: -> 
    @view = new Lunchhub.Views.RestaurantLocations.NewView(collection: @restaurantLocations) 
    $("#restaurant_locations").html(@view.render().el) 

    index: -> 
    @view = new Lunchhub.Views.RestaurantLocations.IndexView(restaurantLocations: @restaurantLocations) 
    $("#restaurant_locations").html(@view.render().el) 

    show: (id) -> 
    restaurant_location = @restaurantLocations.get(id) 

    @view = new Lunchhub.Views.RestaurantLocations.ShowView(model: restaurant_location) 
    $("#restaurant_locations").html(@view.render().el) 

    edit: (id) -> 
    restaurant_location = @restaurantLocations.get(id) 

    @view = new Lunchhub.Views.RestaurantLocations.EditView(model: restaurant_location) 
    $("#restaurant_locations").html(@view.render().el) 

這是我的最新編譯的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; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; 

    Lunchhub.Routers.RestaurantLocationsRouter = (function(_super) { 

    __extends(RestaurantLocationsRouter, _super); 

    function RestaurantLocationsRouter() { 
     RestaurantLocationsRouter.__super__.constructor.apply(this, arguments); 
    } 

    RestaurantLocationsRouter.prototype.initialize = function(options) { 
     this.restaurantLocations = new Lunchhub.Collections.RestaurantLocationsCollection(); 
     return this.restaurantLocations.reset(options.restaurantLocations); 
    }; 

    RestaurantLocationsRouter.prototype.routes = { 
     "new": "newRestaurantLocation", 
     "index": "index", 
     ":id/edit": "edit", 
     ":id": "show", 
     ".*": "index" 
    }; 

    RestaurantLocationsRouter.prototype.newRestaurantLocation = function() { 
     this.view = new Lunchhub.Views.RestaurantLocations.NewView({ 
     collection: this.restaurantLocations 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    RestaurantLocationsRouter.prototype.index = function() { 
     this.view = new Lunchhub.Views.RestaurantLocations.IndexView({ 
     restaurantLocations: this.restaurantLocations 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    RestaurantLocationsRouter.prototype.show = function(id) { 
     var restaurant_location; 
     restaurant_location = this.restaurantLocations.get(id); 
     this.view = new Lunchhub.Views.RestaurantLocations.ShowView({ 
     model: restaurant_location 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    RestaurantLocationsRouter.prototype.edit = function(id) { 
     var restaurant_location; 
     restaurant_location = this.restaurantLocations.get(id); 
     this.view = new Lunchhub.Views.RestaurantLocations.EditView({ 
     model: restaurant_location 
     }); 
     return $("#restaurant_locations").html(this.view.render().el); 
    }; 

    return RestaurantLocationsRouter; 

    })(Backbone.Router); 

}).call(this); 
+0

您是否確認實例化後存在'window.router'?如果'Lunchhub'或'Lunchhub.Routers'未定義,則不能創建'Lunchhub.Routers.RestaurantLocationsRouter',並且'window.router'將不會創建 – jackwanders

+0

'window.router','Lunchhub', 'Lunchhub.Routers','Lunchhub.Routers.RestaurantLocationsRouter'都存在。 –

回答

2

好吧,這竟然是一個非常深奧的問題。儘管我已經切換到使用不同的主幹文件,但我的app/assets/javascripts目錄中有一個剩餘的backbone-min.js。這個「舊」backbone-min.js在我的路由定義後得到加載,這就是搞砸了東西。在我刪除backbone-min.js後,事情開始奏效。

+2

這是我第二次猜測;) – jackwanders