如何在Backbone Marionette中从项视图实例访问复合视图

29
基本情况如下:
我有一个 Composite View 和一个 Item View。我通过传递模型和集合来构建 Composite View。模型数据用于填充 Composite View 的模板。集合数据用于填充 Composite View 的 Item View。
我想做的是:在 Item View 的模板助手中,我想访问 Composite View 的模型数据。我已经可以访问 Item View 的视图实例。我认为这可能会让我掌握 Composite View,从那里我可以获取它的模型,但实际上并不行。
有没有办法可以做到这一点-从其 Item View 实例访问 Composite View 实例?
谢谢
--Justin Wyllie
3个回答

33

如果您想从父CompositeView访问数据,可以采取多种不同的方法。

  1. 通过CompositeView上的itemViewOptions帮助函数直接将数据传递给ItemView。注意:这个选项在Marionette 2中已更改为childViewOptions

  2. 直接在所有子视图上调用一个方法,并将任何您想要的内容传递给该方法。

  3. 触发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));
  }
});

2
谢谢。你很清楚地理解了我的问题——如何将父模型传递给每个子实例。所有三个选项都很有用。 - user911625
3
这是一篇很好的解释。谢谢你! - alettieri
2
请注意,从Marionette 2开始,“itemViewOptions”已更名为“childViewOptions”(以及CollectionView / CompositeView中所有对“itemView”的其他引用)。 - pimlottc
好观点pimlottc。谢谢!更新答案并将其作为注释包含在内。 - Andrew Hubbs
@AndrewHubbs 你让我感到非常开心。谢谢你的回答,给你加一分。 - Nikhil Agrawal

1

我想分享一下 Andrew Hubbs 给我的建议是如何帮助我的。我想在我的 item 模板中内联显示一个父模型属性。我使用了 Marionette 的 templateHelpers 属性以及 Andrew 的其中一个建议来实现这个需求。

以下是我试图简化的示例 Composite 模板 - 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 );

很好的例子。在文档中提到的链接:https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.view.md#accessing-data-within-the-helpers - alxndr

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接