在木偶布局中保持一堆木偶项目视图

时间:2013-10-11 17:30:45

标签: javascript html uinavigationcontroller marionette

我想知道是否有可能以某种方式扩展Marionette Layout基于创建一种类似导航的堆栈的机制。

木偶行为。

在区域show()之前,视图会在当前显示的视图上调用close()close()充当view的析构函数,取消绑定所有事件,使其无用并允许垃圾收集器处理它。

我的情景。

假设我有一种导航机制,其中Layout充当控制器并首先显示名为A的ItemView,然后点击某处允许切换到ItemView B.点,B上的动作(例如点击后退按钮)允许返回A 而不重新创建

如果不再创建A 来维持其状态,如何才能实现上一个场景?

对于iOS用户,我想模仿某种UINavigationController

有什么建议吗?

修改

我的目标是使用其状态恢复上一个缓存视图而不再创建它。

我的方案如下。我有两个区域的布局:A e B. 我在A和A中单击一下,B关闭以显示C和D.现在后退单击将恢复A和B的状态。事件,模型等......但由于视图已关闭,事件将被删除。

2 个答案:

答案 0 :(得分:4)

使用骨干路由器侦听URL更改事件。为每个视图设置路由,然后让路由器调用布局来更改它为响应每个路由而显示的视图。用户可以多次单击向后或向前,应用程序会相应地响应并显示正确的视图。您的路由器可能如下所示:

var Router = Backbone.router.extend({
    routes: {
        'my/route/itemViewA': 'showItemViewA',
        'my/route/itemViewB': 'showItemViewB'
    },

    showItemViewA: function () {
        layout.showItemView('a');
    },

    showItemViewB: function () {
        layout.showItemView('b');
    }
});

您的布局可能如下所示:

var Layout = Backbone.Marionette.Layout.extend({

    regions: {
        someRegion: 'my-region-jquery-selector'
    },

    initialize: function () {
        this.createViews();
    },

    createViews: function () {
        this.views = {
            a: new Backbone.Marionette.ItemView,
            b: new Backbone.Marionette.ItemView
        };
    },

    showItemView: function (view) {
        this.someRegion.show(this.views[view]);

        // You might want to do some other stuff here
        // such as call delegateEvents to keep listening
        // to models or collections etc. The current view
        // will be closed but it won't be garbage collected
        // as it's attached to this layout.
    }
});

路由器和布局之间的通信方法不必是直接呼叫。您可以触发更多应用程序范围的事件或执行您能想到的任何其他事件。上面的路由器是非常基本的,但完成工作。您可以创建一个更智能的路由器来使用带参数的单个路由来动态确定要显示的itemView。

每次用户执行需要更改视图的内容时,您都可以使用router.navigate('my/route/itemViewB', {trigger: true});更新浏览器的历史记录。此外,如果将应用程序设置为仅在历史记录更改事件上呈现,则无需设置两种机制来重新呈现每个视图。

我在自己的应用程序中使用此模式,效果非常好。

答案 1 :(得分:3)

@西蒙的答案正朝着正确的方向前进。但是,阻止Marionette关闭视图的唯一方法是修改它的区域代码。

var NoCloseRegion = Marionette.Region.extend({
    open: function(view) {
        // Preserve the currentView's events/elements
        if (this.currentView) { this.currentView.$el.detach(); } 

        // Append the new view's el
        this.$el.append(view.el);
    }
});

当确保在创建布局视图时指定我们的新Region类

var Layout = Backbone.Marionette.Layout.extend({
    regions: {
        someRegion: {
            selector: 'my-region-jquery-selector',
            regionType: NoCloseRegion
        },
    },
    initialize: function () {
        this.createViews();
    },
    createViews: function () {
        this.views = {
            a: new Backbone.Marionette.ItemView,
            b: new Backbone.Marionette.ItemView
        };
    },
    showItemView: function (name) {
        // Don't `show`, because that'll call `close` on the view
        var view = this.views[name];
        this.someRegion.open(view)
        this.someRegion.attachView(view)
    }
});

现在,不是调用关闭旧视图的show,而是渲染新视图,并将其附加到区域(并触发一些事件),我们可以分离旧视图,附加新视图,然后打开它