基本的な状況はこれです:
複合ビューとアイテムビューがあります。モデルとコレクションを渡してCompositeビューを作成します。モデルデータは、コンポジットビューのテンプレートに入力するために使用されます。コレクションデータは、複合ビューのアイテムビューにデータを入力するために使用されます。
私がやりたいのはこれです:アイテムビューのテンプレートヘルパーで、コンポジットビューのモデルデータにアクセスします。アイテムビューのビューインスタンスにアクセスすることはできます。これにより、コンポジットビューのハンドルが得られるのではないかと思ったのですが、そこからモデルにアクセスできますが、そうではありません。
これを行う方法はありますか?アイテムビューインスタンスの1つから複合ビューインスタンスにアクセスしますか?
ありがとう
-ジャスティン・ワイリー
親CompositeView
からのデータにアクセスする場合は、さまざまなことができます。
ItemView
のitemViewOptions
ヘルパー関数を介して、そのデータを直接CompositeView
に渡します。注:Marionette 2では、このオプションがchildViewOptions
に変更されました。
CompositeView
からすべての子ビューで直接メソッドを呼び出し、必要なものをそのメソッドに渡します。
ItemView
でイベントをトリガーまたはリッスンします。
これらのオプションはいずれも子から親ビューに直接アクセスしていませんが、必要なことを行う必要があります。以下は、これらの各アプローチを使用してCompositeView
のモデルを子ビューに渡す方法のコードです。
// Pass model into ItemView on init
var MyItemView = Backbone.Marionette.ItemView.extend({
initialize : function (options) {
this.parentsModel = options.parentsModel;
}
});
var MyCompView = Backbone.Marionette.CompositeView.extend({
itemViewOptions : function () { return { parentsModel: this.model }; }
itemView : MyItemView
});
// Invoke function on ItemView, passing data in
var MyItemView = Backbone.Marionette.ItemView.extend({
doSomethingWithParent : function (parentModel) {
// do cool thing with parentModel
}
});
var MyCompView = Backbone.Marionette.CompositeView.extend({
itemView : MyItemView,
onRender : function () {
this.children.call("doSomethingWithParent", this.model);
}
});
// Trigger event that ItemView knows about
var MyItemView = Backbone.Marionette.ItemView.extend({
initialize : function () {
this.listenTo(this, "special:event", function (parentModel) {
// Do cool things
});
}
});
var MyCompView = Backbone.Marionette.CompositeView.extend({
itemView : MyItemView,
onRender : function () {
this.children.each(_.bind(function (childView) {
childView.trigger("special:event", this.model);
}, this));
}
});
質問には答えませんでした。しかし、アプローチの変更は機能します。アイテムビューから「親」コンポジットビューにアクセスする代わりに、コンポジットビューからアイテムビューにアクセスします。
(複合ビューのモデルの値に基づいて)現在のアイテムビューのモデルを変更できます。
Andrew Hubbsの提案がどのように私を助けてくれたかを私は共有したいと思いました。親テンプレートプロパティをアイテムテンプレートにインラインで表示しようとしました。 Andrewの提案の1つと組み合わせて、これを行うためにMarionetteのtemplateHelpersプロパティを使用しました。
私は例を簡潔にしようと試みました:
複合テンプレートの例-myViewテンプレート:
<h1>Page {{name}}</h1>
<h6>Children</h6>
<ul></ul>
アイテムテンプレートの例-myItemTemplate:
{{name}} is child of: {{getParentName}}
ビュー:
App.module( 'App.View', function( View ){
View.MyItemView = Marionette.ItemView.extend({
initialize: function( options ) {
this.parentModel = options.parentModel;
},
template: myItemTemplate,
tagName: 'li',
templateHelpers: function() {
var view = this;
return {
// Called by item template, returns parent model 'name' property.
getParentName: function() {
return view.parentModel.get('name');
}
};
}
});
View.MyView = Marionette.CompositeView.extend({
template: myViewTemplate,
itemView: View.MyItemView,
itemViewContainer: 'ul',
itemViewOptions: function() {
return { parentModel: this.model };
}
});
});
これを実装する方法の例:
// example of how implementation
// parent model has an attribute called 'children', which is a collection of models
var children = parent.get('children');
var view = new App.View.MyView( { model: parent, collection: children } );
App.mainRegion.show( view );