2012-11-26 1 views
12

私のbackbone.Marionetteアプリケーションでは、URLを構築するためにId属性が必要なモデルがあります。そこで私は、それを同上を渡すことによって、モデルを作成ビューに追加して、モデルをフェッチ:モデルがフェッチされていない場合、Backbone.Marionetteがビューをレンダリングしないようにするにはどうすればいいですか?

model = new Model({_id:id})    
    view = new View({model:model})        
    app.content.show(view)              
    model.fetch() 

私はモデルがフェッチされたが、マリオネットは、モデルをレンダリングした後にのみレンダリングを開始するビューを期待しますすぐにテンプレートのレンダリングが失敗し、予想される属性が存在しないためです。回避策はありますか?

私はここに受け入れ答えに似た何かをしようとしている:答えで述べたようにそれは、バックボーンと連携しながら、 Binding a Backbone Model to a Marionette ItemView - blocking .fetch()?

しかし、マリオネットは自動的にビューをレンダリングします。

も参照してください:

また
model = new Model({_id:id}); 
view = new View({model:model}); 
model.fetch({success: function() { 
    app.content.show(view); 
}); 

、あなたはすぐにレンダリングを考える必要があると:あなたは本当にモデルは、あなたがこのようなあなたの呼び出しの順序を変更する必要がありフェッチされるまでレンダリングを防止したい場合は Backbone Marionette Displaying before fetch complete

+0

フェッチ後に 'app.content.show()'を遅らせるのは簡単ではないでしょうか?それは、すべての目的のために、モデルがフェッチされるまでビューのレンダリングを遅らせることになります。 –

+1

何らかの読み込みメッセージを表示したい場合は、https://github.com/marionettejs/backbone.marionette/wiki/Displaying-A-%22loading-...%%-Message-For- A-Collection-Or-Composite-View –

答えて

7

をマリオネットの空白状態のサポートを利用しています。 Derickベイリーの例の一つに基づいて

+1

私は似たようなものを使用してしまいましたが、私はそのようなケースを扱うためにマリネットに組み込まれたものがあることを期待していました。ありがとう。 –

+0

マリオネットの*空白状態のサポート*についてもっと説明できますか? – Kevin

2

model = new Model({_id:id})    
    var fetched = model.fetch(); 

    // wait for the model to be fetched 
    $.when(fetched).then(function(){ 

    view = new View({model:model})        
    app.content.show(view)  
    }); 
+0

ありがとう、これは基本的にfetchの成功ハンドラで処理するのと同じですが、私はこれを上回ります。 –

+0

こんにちは、正確には、domがレンダリングされる前にフェッチすることができます。遅延オブジェクトはここで助けます – danikoren

+2

遅延が本当に興味深いのは、複数のデータソースがフェッチされた後にビューをレンダリングする必要がある場合です(http:// davidsulc .com/blog/2013/04/02 /レンダリング-a-view-after-multiple-async-functions-return-using-promises /)したがって、1つのソースだけがフェッチされても遅延コードを使用すると、コードの整合性を保つことができます。 –

10

仕事上の両方の答え。
私は使用したいと思うもう一つの方法があります(感じるmore backboney)。

バインドモデルモデルがフェッチされて実行され
に直接表示、指定した関数が実行されます。 これは、モデルまたはコレクションで行うことができます。

var Model = Backbone.Model.extend({}); 
var model = new Model(); 
model.fetch(); 

var View = Marionette.ItemView.extend({ 
    model:model, 
    initialize: function(){ 
     this.model.bind("sync", this.render, this);// this.render can be replaced 
    }            // with your own function 
});        

app.region.show(new View);           

これにより、いつでも自由にフェッチすることができます。

+2

'.show()'は '.show(new view)'と 'model:sync'を呼び出すときにレンダリングするように渡されたビューで' .render() 'を呼び出します。 – Alex

1

私は同じ問題を再現して、マリオネットのイベントシステムを使用して、showを起動する前にその状態を伝えるようにパターンを決めました。私もいくつかの複雑さを追加するrequireJSを使用しています - しかし、このパターンは役立ちます!

私は、クリックするとイベントを発生させて新しいビューを読み込むUI要素を持つビューを作成します。これは、サブビューまたはnavviewかもしれません - 問題ではありません。

App.execute('loadmodule:start', { module: 'home', transition: 'left', someOption: 'foo' }); 

このイベントはWreqr「setHandlers」でキャッチし、(私の場合、私は状態遷移を処理するためのロジックの束をやってる)ビューのロード・シーケンスをトリガしています。 '開始'シーケンスは新しいビュー内に入り、必要なオプションを渡します。

var self = this; 
App.commands.setHandlers({'loadmodule:start': function(options) { self.start(options); 

次に、読み込み中のビューはコレクション/モデルを処理し、初期化をフェッチします。このビューはモデル/コレクションの変更をリッスンし、wreqrのexecutreコマンドを使用して新しい「準備完了」イベントを起動します。

私は、準備完了イベント(およびビューopject参照を含むオプション)をキャッチし、show()をトリガーする別のハンドラを持っています。

ready: function(options) { 

// catch a 'loadmodule:ready' event before proceeding with the render/transition - add loader here as well 

var self = this; 
var module = options.options.module; 
var view = options.view; 
var transition = options.options.transition; 
var type = options.options.type; 

if (type === 'replace') { 
    self.pushView(view, module, transition, true); 
} else if (type === 'add') { 
    self.pushView(view, module, transition); 
} else if (type === 'reveal') { 
    self.pushView(view, module, transition, true); 
} 

}, 


pushView: function(view, module, transition, clearStack) { 

var currentView = _.last(this.subViews); 
var nextView = App.main.currentView[module]; 
var self = this; 

var windowheight = $(window).height()+'px'; 
var windowwidth = $(window).width()+'px'; 
var speed = 400; 

switch(transition) { 
case 'left': 

    nextView.show(view); 

    nextView.$el.css({width:windowwidth,left:windowwidth}); 
    currentView.$el.css({position:'absolute',width:windowwidth,left:'0px'}); 

    nextView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO); 
    currentView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO, function(){ 

     if (clearStack) { 
      _.each(_.initial(self.subViews), function(view){ 
       view.close(); 
      }); 
      self.subViews.length = 0; 
      self.subViews.push(nextView); 
     } 

    }); 

break; 

私は全体のシステムのまともな要点を書き留めて、次の週程度でここに投稿しようとします。

関連する問題