2

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

木偶行为。

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

我的情景。

假设我有一种导航机制,其中 aLayout充当控制器并首先显示一个ItemView被调用的 A,然后单击某处允许切换到ItemViewB。此时,对 B 的操作(例如点击后退按钮)允许返回 A而不重新创建它

如何在不再次创建 A并维护其状态的情况下实现前面的场景?

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

有什么建议吗?

编辑

我的目标是恢复 prev 缓存视图及其状态,而无需再次创建它。

我的情况如下。我有一个包含两个区域的布局:A e B。我在 A 内的某处单击,A 和 B 已关闭以显示 C 和 D。现在后退单击将恢复 A 和 B 的状态。事件、模型等……但由于视图已关闭,事件已被删除。

4

2 回答 2

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});. 此外,如果您将应用程序设置为仅在历史更改事件上呈现,那么您无需设置两种机制来呈现每个视图。

我在自己的应用程序中使用了这种模式,并且效果很好。

于 2013-10-12T14:22:12.097 回答
3

@Simon 的答案朝着正确的方向前进。然而,阻止 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);
    }
});

在创建 Layout 视图时,一定要指定我们新的 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)
    }
});

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

于 2013-10-22T21:33:21.023 回答