2012-04-02 13 views
44

私のシンプルなプロジェクトでは、広告申込情報(ブランド)とアプリの2つのビューがあります。バックボーンJS:他のビューでトリガアップデートを表示できますか?

 
var BrandView = Backbone.View.extend({ 
...some code... 
    toggle_select: function() { 
     this.model.selected = !this.model.selected; 
     if(this.model.selected) $(this.el).addClass('selected'); 
     else $(this.el).removeClass('selected'); 
     return this; 
    } 
}); 

var AppView = Backbone.View.extend({ 
...some code... 
    delete_selected: function() { 
     _.each(Brands.selected(), function(model){ 
      model.delete_selected(); 
     }); 
     return false; 
    }, 
}); 

何個の項目が選択されているか知りたいですか?この設定では、選択はモデルに影響を及ぼさず、したがってイベントを発生させません。 MVCのコンセプトから、私はビューが他のビューと直接話すべきではないことを理解します。では、BrandViewsで何かが選択されていることをAppViewでどのように知ることができますか?

さらに具体的には、いくつの項目が選択されたかを知るためにAppViewが選択されていますので、複数選択すると、複数選択のメニューが表示されます。

+2

ところで、 '$(this.el).toggleClass( "選択")'。 –

答えて

71

あなたがバックボーンパブ/サブイベントのこの議論の読み取りを持っている場合があります:

http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/

私はグローバルイベントメカニズムとしてそれを追加したい:

Backbone.pubSub = _.extend({}, Backbone.Events); 

次に、1つのビューでイベントをトリガーできます。

Backbone.pubSub.trigger('my-event', payload); 

別では、あなたは聞くことができます。

ジョンと同じ
Backbone.pubSub.on('my-event', this.onMyEvent, this); 
+0

実際これはまさに私が最終的にhttp: /lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/それを使用し始めました。良いことです。ありがとう) –

+0

これは本当に助けになりました大きな時間がありました。ありがとうございます。 – Bharat

+0

上にコメントする..ありがとう! – Alex

1

あなたの投稿に既に言及しているこの問題を無視して、何か他のものと話すことを可能にするグローバルBackbone.Eventオブジェクトとの間でイベントをバインドおよびトリガーできます。間違いなく最適なソリューションではなく、お互いにチャットしているビューがある場合は、そのリファクタリングを検討する必要があります。しかし、そこに行く!お役に立てれば。

7

私はAddy Osmaniがメディエーター・パターンhttp://addyosmani.com/largescalejavascript/#mediatorpatternと呼んでいるものを使用します。記事全体は読みに値するものです。

基本的に、イベントを購読して公開できるイベントマネージャです。つまり、AppViewはイベント、つまり「選択済み」に添字を付けます。次に、BrandViewは 'selected'イベントを公開します。

私が好きなのは、ビューを直接バインドしなくても、ビュー間でイベントを送信できるからです。例

var mediator = new Mediator(); //LOOK AT THE LINK FOR IMPLEMENTATION 

var BrandView = Backbone.View.extend({ 
    toggle_select: function() { 
     ... 
     mediator.publish('selected', any, data, you, want); 
     return this; 
    } 
}); 

var AppView = Backbone.View.extend({ 
    initialize: function() { 
     mediator.subscribe('selected', this.delete_selected) 
    }, 

    delete_selected: function(any, data, you, want) { 
     ... do something ... 
    }, 
}); 

については

それは選択された 'イベントを発行していBrandViewかFooViewであればアプリのビューは、イベントが発生したことだけが、気にしないこの方法です。その結果、ビューだけでなく、アプリケーション間のイベントを管理するための維持可能な方法が見つけられました。

「Facade」についてさらに詳しく知っていれば、素晴らしいアクセス許可構造を作成できます。これにより、「AppView」だけが「選択された」イベントに登録できると言うことができます。これは、イベントがどこで使用されているかを非常に明確にするので、これが役に立ちます。

+0

これはバックボーンでネイティブにサポートされていますか? –

+0

これはバックボーンの一部ではありませんが、これはバックボーンの一部ではありません。あなたがあなたのビューを変更しようとしているときに非常に混乱してしまう別のビューにあるビューのDOMイベントを直接バインドする場合は、私が意味するものを明確にしようと私の答えを更新します。 –

0

同じモデルオブジェクトを使用してください。 AppViewをコレクションで初期化し、BrandViewをそのコレクションの1つのモデルで初期化することができます。分岐オブジェクトの属性が変更されると、そのモデルへの参照を持つ他のコードでも読み取ることができます。

だからそう、あなたがコレクションを経由してフェッチいくつかのブランドを持っていることができます:

var brands = new Brands([]); 
brands.fetch(); 

今、あなたはAPPVIEWを行い、各モデルのBrandViewの配列。

var appView = new AppView({brands: brands}); 
var brandViews = brands.map(function(brand) { 
    return new BrandView({brand: brand}); 
}); 

APPVIEWとbrandViewsは現在、両方とも同じモデルオブジェクトへのアクセス権を持っているので、あなたは1を変更する場合:

brands.get(0).selected = true; 

だけでなく、それを参照するビューがアクセスしたときにそれが変更されます。

console.log(appView.brands.get(0).selected); // true 
console.log(brandViews[0].brand.selected) // true 
+0

あなたの最初の2つのコード例は既に使用されています。そして、私は選択されたブランドの数を取得する方法を知っています質問は、どのViewが別のViewで選択/選択解除されたことを知ることができますか? –

0

をMediatorパターンは、アディOsmaniがBackbone fundamentalsに再びこの問題を合計して、このシナリオでは本当に良い作品、上記提案しています。シンプルで素晴らしいです、そして私のAMDビュー=シームレスに一緒に働いてモジュールになりBackbone.Mediatorプラグインを使用して巻き取っ

)ここで

1

は、同様のニーズを持つ私の場合です:バックボーンlistenToは、ログインするためにリダイレクトするためのソリューションのように思えましたタイムアウトまたは認証されていない要求のページ。

私は私のルータにイベントハンドラを追加し、それはのようなグローバルイベントに耳を傾ける行わ:

Backbone.Router.extend({ 
    onNotAuthenticated:function(errMsg){ 
     var redirectView = new LoginView(); 
     redirectView.displayMessage(errMsg); 
     this.loadView(redirectView); 
    }, 
    initialize:function(){ 
     this.listenTo(Backbone,'auth:not-authenticated',this.onNotAuthenticated); 
    }, 
    ..... 
}); 

と私のjqueryのAjaxのエラーハンドラで:

$(document).ajaxError(
    function(event, jqxhr, settings, thrownError){ 
     ....... 
     if(httpErrorHeaderValue==="some-value"){ 
      Backbone.trigger("auth:not-authenticated",errMsg); 
     } 
    });  
+0

Backbone.on()が動作しない場所でthis.listenTo()が動作しました... –

1

あなたはバックボーンを使用することができますイベントバスとしてのオブジェクト。

このアプローチはややきれいですが、まだグローバルバックボーンオブジェクトに依存しているものの

var view1 = Backbone.View.extend({ 

    _onEvent : function(){ 
    Backbone.trigger('customEvent'); 
    } 

}); 


var view2 = Backbone.View.extend({ 

    initialize : function(){ 
    Backbone.on('customEvent', this._onCustomEvent, this); 
    }, 

    _onCustomEvent : function(){ 
    // react to document edit. 
    } 

}); 
関連する問題