2013-05-31 4 views
9

私は領域を持つレイアウトビューを持っています。その領域にはイベントをトリガするアイテムビューがありますが、レイアウトビューまではバブルしていないようです。間違ったことをやっているのですか?親ビューはコレクションビューではないので、itemview接頭辞は追加されないと思いますか?どちらの場合でも、イベントは決してレイアウトビューにバブリングされません。itemviewからparent layoutviewへのマリオネットバブルイベント?

layoutView = Marionette.Layout.extend({ 
     template: "#layout-template", 
     regions: { 
      titleRegion: "#job-title-region" 
     }, 
     triggers: { 
      "save:clicked" : "onSaveClicked" 
     }, 
     onSaveClicked: function (args) { 
      alert('Clicked'); 
     } 
    }); 

childview = Marionette.ItemView.extend({ 
     template: "#child-template", 
     triggers: { 
      "click .js-save": "save:clicked" 
     } 
    }); 

UPDATE:

このフィドルhttp://jsfiddle.net/7ATMz/11/を参照してください。私は子供のイベントに耳を傾けるために、レイアウトビューを得ることができたが、私は、レイアウトビュー自体の外側をそれを配線し、カプセル化を破ることがあります。とにかくレイアウトビューでこれを行うことはできますか?

おかげで、

ジョン

答えて

0

はなぜちょうどバブルにDOM階層をクリックしてイベントを起動できるようにして、レイアウトビューでそれを処理しませんか?このような何か(フィドルhere):

var MainView = Marionette.Layout.extend({ 
    template: "#layout-template", 
    regions: { 
     childRegion: "#childRegion" 
    }, 
    events: { 
     'click #btn': 'handleButtonClick' 
    }, 
    handleButtonClick: function() { 
     alert('btn clicked in child region and bubbled up to layout'); 
    } 
}); 

var ChildView = Marionette.ItemView.extend({ 
    template: "#child-template" 
    /* 
    triggers: { 
     "click #btn": "btn:clicked" 
    }*/ 
}); 
+0

このレイアウトの子領域のビューからイベントを発生させるとうまくいかないようですか? – Jon

+0

申し訳ありませんが、それは本当に少しの推測でした。クリックイベントは、DOM階層をレイアウトビューにバブルアップして、通常のイベントオブジェクトを使用してレイアウト内でキャッチする必要があります。 –

+0

シンプルなhttp://jsfiddle.netの例をまとめることができますか? –

10

トリガーは非常にそのように動作しません:あなたのレイアウトは、間違ったそれらを使用しています。トリガーは、特定のインタラクション(クリックなど)がある場合にイベント信号を発生させるのに便利です。

トリガーメソッド(https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.functions.md#marionettetriggermethod)を使用してレイアウト内の関数をトリガーします。

childView.on("btn:clicked", function(){ 
    layout.triggerMethod("childView:btn:clicked"); 
}); 

そして、あなたのレイアウトで:のみバブリング

onChildViewBtnClicked: function(){ 
    https://leanpub.com/marionette-gentle-introduction 
}); 

イベントは、コレクションに自動的に起こる複合ビューを彼らはしっかりと自分のアイテムに関連付けられているので、?あなたのshow機能でこれをしたい、基本的にhttp://jsfiddle.net/ZxEa5/を参照してください。再生回数レイアウトで子ビューの1つを監視するには、それを自分で設定する必要があります。

恥知らずのプラグイン:Marionetteでコードを構造化してクリーンアップする方法について詳しく知りたい場合は、このタイプの概念(およびそのアプリケーション)について詳しく説明している私の書籍(https://leanpub.com/marionette-gentle-introduction)をチェックすることができます。

+1

私の謙虚な意見では、レイアウトが子どもたちからのバブルイベントをすべて自動的に処理するのであれば、より直感的です。それ以外の場合は、例外エラーまたは少なくともイベントがまったく処理されなかったという警告を除きます。これらのどれも最新のマリネットのバージョンでは発生しません –

1

次のような同様の問題の解決法を実装しました。二回マリオネットからの定期的なtriggerMethodを呼び出します

Marionette.View.prototype.bubbleMethod = function() { 
    var args = _.toArray(arguments) 
    var event = args.shift() 
    var bubble = event + ':bubble' 
    this.triggerMethod.apply(this, [ event ].concat(args)) 
    this.triggerMethod.apply(this, [ bubble ].concat(args)) 
} 

:まず、私は右のMarionette.Viewプロトタイプに新しい方法を書いたことが意図されるようにイベント名で一度に処理すること、及び第二の一つはイベントをバブリングするように指定された特殊なビューによって容易に認識されます。

次に、バブルアップされるような特殊なビューおよびバブルアップイベントが必要です。他のビューに代わってclose(まったくのマリオネットイベント)のようなイベントをディスパッチしないように注意する必要があります。これは、リージョンとビューであらゆる種類の予期しない動作が発生するためです。 :bubbleの接尾辞を使用すると、バブルの意味を簡単に認識できます。バブリングビューは次のようになります。

var BubblingLayout = Marionette.Layout.extend({ 
    handleBubbles: function (view) { 
     var bubble = /:bubble$/ 
     this.listenTo(view, 'all', function() { 
      var args = _.toArray(arguments) 
      var event = args.shift() 
      if (event.match(bubble)) { 
       event = event.replace(bubble, '') 
       this.bubbleMethod.apply(this, [ event ].concat(args)) 
      } 
     }, this) 
    } 
}) 

あなたがいることを確認する必要があり、最後のものは、(カスタム領域マネージャーとのレイアウトとモジュールの)地域でバブルイベントにできるようにすることです。それはこのように、地域からshowイベントディスパッチで扱うことができます。

var MyView = Marionette.ItemView.extend({ 
    events: { 
     'click': 'clickHandler' 
    }, 
    clickHandler: function (ev) { 
     // do some stuff, then bubble something else 
     this.bubbleMethod('stuff:done') 
    } 
}) 

var BubblingLayout = Marionette.Layout.extend({ 
    regions: { 
     sidebar: '#sidebar' 
    }, 
    initialize: function() { 
     this.sidebar.on('show', this.handleBubbles, this) 
    }, 
    onRender: function() { 
     var view = new MyView() 
     this.sidebar.show(view) 
    }, 
    handleBubbles: function (view) { 
     var bubble = /:bubble$/ 
     this.listenTo(view, 'all', function() { 
      var args = _.toArray(arguments) 
      var event = args.shift() 
      if (event.match(bubble)) { 
       event = event.replace(bubble, '') 
       this.bubbleMethod.apply(this, [ event ].concat(args)) 
      } 
     }, this) 
    } 
}) 

var BubblingLayout = Marionette.Layout.extend({ 
    regions: { 
     sidebar: '#sidebar' 
    }, 
    initialize: function() { 
     this.sidebar.on('show', this.handleBubbles, this) 
    }, 
    handleBubbles: function (view) { 
     var bubble = /:bubble$/ 
     this.listenTo(view, 'all', function() { 
      var args = _.toArray(arguments) 
      var event = args.shift() 
      if (event.match(bubble)) { 
       event = event.replace(bubble, '') 
       this.bubbleMethod.apply(this, [ event ].concat(args)) 
      } 
     }, this) 
    } 
}) 

最後の部分は簡単に新しいbubbleMethod方法によって処理されます何か、実際にバブルアップを作ることです

BubblingLayoutのインスタンスにアクセスできるコード内の任意の場所からバブリングされたイベントを処理できます。

4

私は必要性のこのタイプのBackbone.Courierを使用することをお勧めします:https://github.com/rotundasoftware/backbone.courier

+3

この例を超えて、ItemViewsから親のCollectionViewにイベントをバブリングするために、Marionetteに既に実装されているものよりもCourierを使用することをお勧めしますか? – backdesk

7

このマリオネット機能が導入されたとき、私はわからないんだけど、はるかに簡単な解決策はchildEventsハッシュを使用することになります。http://marionettejs.com/docs/v2.4.1/marionette.layoutview.html#layoutview-childevents

... 
childEvents: { 
    "save:clicked" : "onSaveClicked" 
}, 
... 

それがより理にかなっている場合は、直接このように、LayoutViewの外機能に子イベントをバインドできます。

layout.on('childview:save:clicked', function(childView) { 
    alert('clicked'); 
} 
+0

それを試しても動作しませんでした。それはあなたのために働いたのですか?私はそのレイアウトを子の 'listenTo'に明示的に伝えなければなりませんでした。例えば、 'this.listenTo(this.announcementRegion.currentView、" poisonpill "、()=> { this.announcementRegion.empty() });' –

+0

いいえ、それは私のためにうまく動作します、私は試しましたこれは、CollectionView、LayoutView、およびCompositeViewのためのものです。 – kprist

+0

これは素晴らしい、最新の解決策です! – Seth

関連する問題