4

使用 MarionetteJS v1.0.3。

我有一个Marionette.Layout有两个区域的实例。

第一个区域是CompositeView左边的a,另一个区域是ItemView右边的a。

CompositeView 呈现多个 ItemView。

这个想法是,用户单击左侧集合中的一个项目,以在右侧的 ItemView 上完整显示所选记录。

顶部的Layout如何订阅链中的事件:Layout > Region > CompositeView > ItemView

由于顶部的 Layout 是唯一知道右侧详细区域的布局,因此需要从触发 click 事件的 CompositeView 一路消耗事件。我知道有全局事件,但它们是全局的,并且可能同时运行多个布局,因此它们的事件会发生冲突。

LeftListPanelView = Marionette.CompositeView.extend({

    template: "#leftPanel",
    itemViewContainer: "ul",

    events: {
        "click li": "rowClicked"
    },

    rowClicked: function (e) {
        var itemid = $(e.currentTarget).data("itemid") * 1;
        var selectedItem = this.collection.get(itemid);

        if (selectedItem) {
            this.trigger("itemSelected", selectedItem);
        }
    }
});
4

2 回答 2

10

简而言之,您可以在显示您的以下内容后绑定到该CompositeView事件Layout

yourLayout.region.currentView.on('item:clicked', yourFunction);

这是比使用全局事件更好的解决方案。全局事件适用于“这是与我的应用程序状态全局相关的事件”的语义推理,并且(在我看来)实际上代表了一种反模式,仅在项目架构变得混乱并需要重构时才需要使用.

事件的最佳方法是始终从发生事件的对象中触发事件,并始终监视触发它们的对象上的事件。

于 2013-07-14T23:14:57.197 回答
7

只需使用事件。当用户点击一个项目时,会触发一个带有MyApp.trigger("item:clicked", myItemInstance). 然后,在您的布局中,只需使用

MyApp.on("item:clicked", function(myItemInstance){
   // do stuff
});

请注意,您还可以“自动”触发从 itemView 气泡到集合/复合视图的事件(请参阅https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.collectionview.md#itemview -event-bubbling-from-child-views )

您可以在此处查看使用事件控制应用行为的示例:https ://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/apps/contacts/list/list_controller.js

该代码摘自我正在写的关于 Marionette 的书中:https ://leanpub.com/marionette-gentle-introduction (此处提供免费示例:http: //samples.leanpub.com/marionette-gentle-introduction-sample。 .pdf )

于 2013-05-31T07:24:00.117 回答