0

backbone-rails gem のこの例https://github.com/codebrew/backbone-rails#example-usageに従っています。1 つの単語名を持つモデルでは問題なく動作しますがUncaught TypeError: Cannot call method 'bind' of undefined、2 つの名前を持つモデルに対して同じパターンに従おうとするとエラーが発生します。これが私がしたことです:

rails new blog

rails-backbone次に、gemをGemfileに追加しました

bundle install

rails g backbone:install

rails g scaffold FriendRequest sender_gender:string recipient_gender:string

rake db:migrate

rails g backbone:scaffold FriendRequest sender_gender:string recipient_gender:string

私のapp/views/friend_requests/index.html.erbファイルは次のようになります。

<h1>Listing friend_requests</h1>

<table>
  <tr>
    <th>Sender gender</th>
    <th>Recipient gender</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @friend_requests.each do |friend_request| %>
  <tr>
    <td><%= friend_request.sender_gender %></td>
    <td><%= friend_request.recipient_gender %></td>
    <td><%= link_to 'Show', friend_request %></td>
    <td><%= link_to 'Edit', edit_friend_request_path(friend_request) %></td>
    <td><%= link_to 'Destroy', friend_request, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New Friend request', new_friend_request_path %>


<div id="friend_requests"></div>

<script type="text/javascript">
  $(function() {
    // Blog is the app name
    window.router = new Blog.Routers.FriendRequestRouter({friend_requests: <%= @friend_requests.to_json.html_safe -%>});
    Backbone.history.start();
  });
</script>

ヒットするhttp://localhost:3000/friend_requestsと、このエラーが表示されます

Uncaught TypeError: Cannot call method 'bind' of undefined 

内部のエラーを示すコンソールからコードをコピーしました。このようなエラーが発生した StackOverflow の正しいプロトコルはわかりませんが、* で囲まれていることがわかります。誰かがこの質問を編集して適切に表示したい場合は、それをいただければ幸いです。

(function() {
  var _base,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    __hasProp = {}.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; };

  (_base = Blog.Views).FriendRequests || (_base.FriendRequests = {});

  Blog.Views.FriendRequests.IndexView = (function(_super) {

    __extends(IndexView, _super);

    function IndexView() {
      this.render = __bind(this.render, this);

      this.addOne = __bind(this.addOne, this);

      this.addAll = __bind(this.addAll, this);
      return IndexView.__super__.constructor.apply(this, arguments);
    }

    IndexView.prototype.template = JST["backbone/templates/friend_requests/index"];

    IndexView.prototype.initialize = function() {
      return this.options.friendRequests.bind('reset', this.addAll);
***Uncaught TypeError: Cannot call method 'bind' of undefined***
    };

    IndexView.prototype.addAll = function() {
      return this.options.friendRequests.each(this.addOne);
    };

    IndexView.prototype.addOne = function(friendRequest) {
      var view;
      view = new Blog.Views.FriendRequests.FriendRequestView({
        model: friendRequest
      });
      return this.$("tbody").append(view.render().el);
    };

    IndexView.prototype.render = function() {
      $(this.el).html(this.template({
        friendRequests: this.options.friendRequests.toJSON()
      }));
      this.addAll();
      return this;
    };

    return IndexView;

  })(Backbone.View);

}).call(this);

index_view.js.coffee最後に、上記のエラーを生成するcoffeescript ファイルは次のとおりです。

Blog.Views.FriendRequests ||= {}

class Blog.Views.FriendRequests.IndexView extends Backbone.View
  template: JST["backbone/templates/friend_requests/index"]

  initialize: () ->
    @options.friendRequests.bind('reset', @addAll)

  addAll: () =>
    @options.friendRequests.each(@addOne)

  addOne: (friendRequest) =>
    view = new Blog.Views.FriendRequests.FriendRequestView({model : friendRequest})
    @$("tbody").append(view.render().el)

  render: =>
    $(@el).html(@template(friendRequests: @options.friendRequests.toJSON() ))
    @addAll()

    return this

2 つの名前を持つモデルに対して適切な大文字化やその他の規則を使用しないなどの単純なものであると想定していますが、それを理解できないようです。

前もって感謝します!

編集 - - -

app/views/friend_requests/index.html.erb私はちょうどこれについて考えましたが、実際に自分のコードを手作業で編集した唯一の場所であるため、自分のファイルに細心の注意を払います。それ以外はすべてrails-backbonegem によって自動生成されます。

--------編集#2--------------

IndexView がインスタンス化された場所を尋ねる最初のコメントによると、次の場所にあります/app/assets/javascripts/backbone/routers/friend_requests_router.js.coffee

class Blog.Routers.FriendRequestsRouter extends Backbone.Router
  initialize: (options) ->
    @friendRequests = new Blog.Collections.FriendRequestsCollection()
    @friendRequests.reset options.friendRequests

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

  newFriendRequest: ->
    @view = new Blog.Views.FriendRequests.NewView(collection: @friend_requests)
    $("#friend_requests").html(@view.render().el)

  index: ->
    @view = new Blog.Views.FriendRequests.IndexView(friend_requests: @friend_requests)
    $("#friend_requests").html(@view.render().el)

  show: (id) ->
    friend_request = @friend_requests.get(id)

    @view = new Blog.Views.FriendRequests.ShowView(model: friend_request)
    $("#friend_requests").html(@view.render().el)

  edit: (id) ->
    friend_request = @friend_requests.get(id)

    @view = new Blog.Views.FriendRequests.EditView(model: friend_request)
    $("#friend_requests").html(@view.render().el)
4

1 に答える 1

0

あなたのルーターはこれを行います:

index: ->
  @view = new Blog.Views.FriendRequests.IndexView(friend_requests: @friend_requests)
  #...

部分に注意してくださいfriend_requests:。ただし、あなたBlog.Views.FriendRequests.IndexViewは常に探してい@options.friendRequestsます:

initialize: () ->
  @options.friendRequests.bind('reset', @addAll)

バックボーンが処理します@options

新しいビューを作成するときに、渡したオプションはthis.options、後で参照できるように、としてビューに添付されます。

ただし、下線付きの名前はキャメルケースの名前に変換されません。ビューは、@options.friend_requestsではなく見ている必要があります@options.friendRequests(またはfriendRequests:、ビューをインスタンス化するときに使用します)。変数の命名規則(小文字とアンダースコアまたはキャメルケース)を1つだけに固執することをお勧めします。アンダースコアはRubyとRailsでより一般的であるため、適切な選択となる可能性があります(OTOH、キャメルケースはJavaScriptでかなり一般的です...)。

PS:バックボーンビューにはすでにjQueryバージョンの@elinが含まれているため、どこにでも@$el移動する必要はなく、を使用するだけです。$(@el)@$el


バックボーン1.1.0アップデート:1.1.0以降、バックボーンビューはビューのオプションに自動的に設定されなくなりthis.optionsました。その動作が必要な場合は、自分で行う必要があります。

initialize: (options) ->
  @options = options
  #...

また:

initialize: (@options) ->
  #...

また、必要なオプションを取得しoptionsて、残りを破棄することもできます。

initialize: (options) ->
  @friend_requests = options.friendRequests
  #...

ビューのオプションが非常に明確で追跡しやすいので、後者のアプローチをお勧めします。

于 2012-11-04T00:25:33.840 に答える