2013-05-14 10 views
18

backbone.jsモデルフェッチメソッドの使用について非常に混乱しています。backbone.jsモデルフェッチメソッドの動作方法

profile: function(id) { 
    var model = new Account({id:id}); 
    console.log("<---------profile router-------->"); 
    this.changeView(new ProfileView({model:model})); 
    model.fetch(); 
} 

最初のステップは、モデルアカウントがインスタンス化され、アカウントのモデルは次のようになります。次の例
バックボーンルータを参照してください。

define(['models/StatusCollection'], function(StatusCollection) { 
    var Account = Backbone.Model.extend({ 
    urlRoot: '/accounts', 

    initialize: function() { 
     this.status  = new StatusCollection(); 
     this.status.url = '/accounts/' + this.id + '/status'; 
     this.activity  = new StatusCollection(); 
     this.activity.url = '/accounts/' + this.id + '/activity'; 
    } 
    }); 

    return Account; 
}); 

何のためのurlRootプロパティですか?モデルオブジェクトが作成された後、プロファイルビューはthis.changeView(新しいProfileView({model:model}))でレンダリングされます。の場合、changeview関数は次のようになります。

changeView: function(view) { 
    if (null != this.currentView) { 
    this.currentView.undelegateEvents(); 
    } 
    this.currentView = view; 
    this.currentView.render(); 
}, 

ビューをレンダリングした後に、プロファイル情報は、まだ表示されませんが、model.fetch後();文が実行され、モデルからのデータが表示されます。なぜですか?私は実際にフェッチの仕組みがわからないので、私は見つけようとしますが、チャンスはありません。

答えて

38

私はあなたの質問がここにあるかどうかは完全にはわかりませんが、私ができることを説明するために最善を尽くします。

urlRootの背後にあるコンセプトは、それが基本URLになり、子要素がそのurlRootに追加されたIDでその下にフェッチされることです。

たとえば、次のコード

var Account = Backbone.Model.extend({ 
    urlRoot: '/accounts' 
}); 

は、ベースURLを設定します。その後、)これをインスタンス化(フェッチ呼び出しした場合:そこにあなたの場合は

GET /accounts/abcd1234 

、あなたがurlRootを設定して、明示的にURLを設定している:

var anAccount = new Account({id: 'abcd1234'}); 
anAccount.fetch(); 

それは次のリクエストになるだろうあなたが提供したurlRootは無視されます。

私はURLが導出される方法を確認するために(それは驚くほど簡潔です)バックボーンソースを検討することをお勧め:http://backbonejs.org/docs/backbone.html#section-65

あなたの他の質問に答えるために、あなたのプロファイル情報がすぐに表示されません理由は、(それがフェッチされ)は、ネットワークに出て、あなたのサーバーに行き、返信が表示されるまで待たなければなりません。

これは即時ではありません。

これはノンブロッキングのやり方で行われます。つまり、リクエストを行い、何をしているのかを確認し、リクエストがサーバーから戻ってくると、Backboneが何か他のことを確認するために使用するイベントを発生させます。あなたがモデルのデータを持っているので、実行しなければならなかったことが実行されます。

私はここで何が起こっているかを説明するために、あなたのスニペットにいくつかのコメントを入れている:

profile: function(id) { 
    // You are instantiating a model, giving it the id passed to it as an argument 
    var model = new Account({id:id}); 
    console.log("<---------profile router-------->"); 

    // You are instantiating a new view with a fresh model, but its data has 
    // not yet been fetched so the view will not display properly 
    this.changeView(new ProfileView({model:model})); 

    // You are fetching the data here. It will be a little while while the request goes 
    // from your browser, over the network, hits the server, gets the response. After 
    // getting the response, this will fire a 'sync' event which your view can use to 
    // re-render now that your model has its data. 
    model.fetch(); 
} 

ですから、モデルはあなたができるいくつかの方法があるフェッチされた後、あなたのビューが更新されていることを確認したい場合それを行う:(1)成功コールバックをモデルに渡す。fetch()(2)ビューのハンドラを登録して 'sync'イベントを監視し、返されたときにビューを再レンダリングします。(3)成功コールバックでビューをインスタンス化するためのコードを配置します。ネットワークリクエストが返ってモデルにデータがあるまで生成されます。

+0

まずはお返事ありがとうございます。とてもいい説明です。 fetch()が 'sync'イベントを発生させた後、ビューが自動的にレンダリングされます。あなたが私に与える提案は、いくつかの例を作ることができますか、私はかなりbackbonejsとjavascriptで私はよくその言語をよく知っているが、あまりよく知らない。 –

+0

urlrootが正しく上書きされますか?このvarベースのCuz = _result(this、 'urlRoot')|| _.result(this.collection、 'url')|| urlError(); –

+0

最初の質問では、同期イベントは自動的にビューをレンダリングしません。これを有効にするには、次のように追加します。 "view.on( 'sync'、this.render、this);" –

関連する問題