1

私のBackbone.jsには、次のものがあります

class ParentView extends Backbone.View
  el:"#main"

  childView : new ChildView

  render: =>
    $(@el).empty().append(@childView.render().el)


class ChildView extends Backbone.View

  render: =>
    $.ajax
      url:"get_data"
      success: (data) =>
        $(@el).empty().append("Child View done")
        @

子ビューの関数は AJAX 呼び出しを行い、親ビューの関数はAJAX が終了するのを実際には「待機」しないParentViewため、何も表示されません。renderrender

これを達成する一般的な方法は何ですか?

4

3 に答える 3

1

$.ajax呼び出しは非同期であり、promiseを返し、renderメソッドはこのpromiseを返します。この概念をよりよく理解するために、jsの非同期性について何かを読むことをお勧めします。

そして、あなたが達成したいことは、通常、次のように行われます。

class ChildView extends Backbone.View
  initialize: ->
    @on 'data:fetched', @render

  render: =>
    @$el.html("Child View done")
    @

  fetch: =>
    $.ajax
      url: "get_data"
      success: (data) =>
        # process data and attach it to view
        @trigger 'data:fetched'

ところで、すべてのデータアクセス/操作ロジックをモデルレイヤー(モデルとコレクション)に配置することをお勧めします。この場合、次のようなことができます。

class ChildView extends Backbone.View
  initialize: ->
    @collection.on 'reset', @render
    # call @collection.fetch() somewhere
    # or use @model.on 'change', @render to bind rendering to model changes

  render: =>
    @$el.html("Child View done")
    @
于 2013-03-09T09:16:02.443 に答える
1

nl_0の答えが言ったように。ajax 呼び出しから約束を返しています。返したいもの、または返すことを意図したもの@は、子ビュー インスタンスです。nl_0 は、データのフェッチ方法についても正しいです。バックボーン モデルとコレクション データ レイヤーを使用するのではなく、ajax 呼び出しからデータをフェッチする場合、バックボーンを実際に使用しているわけではありません。そのため、彼の回答に投票するつもりですが、以下が問題の説明に役立つことを願っています.

何が起こっているのですか:

class ParentView extends Backbone.View
   el:"#main"

  childView : new ChildView

  render: => 
    $(@el).empty().append(@childView.render().el)
    // because of the subtle mistakes in @childView.render() below
    // your childView never got anything appended to it.
    // @childView.render().el is undefined
    // essentially $(@el).empty().append(undefined)
    // that's why nothing shows up.


class ChildView extends Backbone.View

  render: =>
    $.ajax
      url:"get_data"
      success: (data) =>
        // @ is not a reference to your child view.
        // the value of @ has changed context
        // that means @el is undefined.
        // You're selecting $(undefined) not your views element.
        $(@el).empty().append("Child View done") 
        @ // this is not your ChildView instance

あなたができることは次のとおりです。

 class ParentView extends Backbone.View
   el:"#main"

  childView : new ChildView

  render: => 
    // this line is actually okay if we fix @childView.
    $(@el).empty().append(@childView.render().el)


class ChildView extends Backbone.View

  onSuccess: (data) =>
    // the double arrow binds this function to the proper context
    // @ is our ChildView instance
    @$el.empty().append("GET get_data is done.")

  render: =>
    $.ajax
      url:"get_data"
      success: @onSuccess

    // return @ out here where it is the instance.
    // This is really where "Child View done".
    @

間違いがありましたら申し訳ありません。私のコーヒースクリプトのスキルはかなり使われていません。これがあなたの言いたいことだと思います。非常に微妙なことです。この回答を編集する必要がある場合はお知らせください。

childView.render().elajax 呼び出しにかかる時間によっては、dom に追加されるため、ajax 呼び出しが戻ってきて "GET get_data is done" を追加する前に、わずかな遅延が発生する場合があります。

于 2013-03-09T10:28:25.477 に答える
0

これを実現するための典型的なバックボーン パターンは次のようになります。

render: =>
  $.ajax
    url:"get_data"
    success: (data) =>
      #when the ajax call returns, modify the contents of the view's el
      @$el.empty().append("Child View done")

  @ #return this

基本的に、renderメソッドは ajax リクエストを開始し、すぐに呼び出し元に制御を返します。ajax リクエストが返されると、ビューの内容が変更されますが、ビューの要素は変更されません。

これは、親ビューchildView.elが独自に追加される場合、childView.render同期か非同期かは問題にならないことを意味します。ルート要素 elは、すでに内容があるかどうかに関係なく存在します。

@$el.empty().append(@childView.render().el)

jQuery セレクター ( )view.$elでラップする代わりに、プロパティを使用することも重要です。前者は、ビューの要素が DOM に存在するかどうかに関係なく機能しますが、後者は、ajax 要求が成功するまでに親ビューが完全にレンダリングされていない場合に失敗します。view.el$(@el)

于 2013-03-09T09:11:39.270 に答える