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ました。私は今、奇妙な問題を抱えていますが、潜在的に簡単なものです: コンパイルされた 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);
4

1 に答える 1

2

さて、これはかなり難解な問題であることが判明しました。別のバックボーン ファイルの使用に切り替えたにもかかわらずbackbone-min.js、ディレクトリに残り物が残っていました。app/assets/javascriptsこの「古い」は、ルート定義のbackbone-min.jsにロードされていたため、混乱していました。を削除した後、動作が始まりました。backbone-min.js

于 2012-06-26T20:40:23.380 に答える