2

我有以下代码块。它完美地工作。

<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-railsgem 自动生成):

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 中,它restaurant_locations在一些本应使用restaurantLocations. 我现在遇到了一个奇怪的问题,但可能是一个更简单的问题:当我在分配<script>之前将编译后的 JavaScript 直接复制并粘贴到区域中时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);
4

1 回答 1

2

好的,结果证明这是一个非常深奥的问题。尽管我已经切换到使用不同的 Backbone 文件,但我的目录backbone-min.js中仍有剩余。在我的路线定义之后app/assets/javascripts,这个“旧”backbone-min.js被加载了,这就是把事情搞砸的原因。在我删除之后,事情开始起作用了。backbone-min.js

于 2012-06-26T20:40:23.380 回答