0

我目前正在开发一个大规模的 Backbone 应用程序(使用 marionetteJS),并且在切换视图或更改“页面”所涉及的最佳实践/模式方面遇到了一些架构问题。

Marionette 的布局和区域为进行视图切换提供了一些非常棒的工具,例如.show().empty()方法。在我正在开发的应用程序中,我使用了一个布局视图作为所有其他视图的容器,这允许我切换视图进出,本质上是在应用程序中导航。

这很容易。对我来说,困难的部分是了解触发这些变化的最佳实践是什么。

以下是我提出的一些解决方案:

  1. page:change:x当用户单击 ui 的某个部分(x 是要更改的视图)时会触发一个事件。管理该视图的控制器侦听该事件并将其显示在应用程序主布局视图中。

  2. 当用户单击 ui 更改页面时,视图会触发一个命令,并在视图中传递它希望 ui 更改为的视图,例如App.execute('page:change', view). 应用程序对象监听那个触发器,并显示传递给应用程序主布局视图的视图。

第一种方法的问题是控制器必须知道其范围内的每个页面(也许这不是一件坏事,我不知道)。例如:users-list-view、users-edit-view、users-profile-view 等。这也使得代码更难跟踪,因为到处都有事件被触发。

第二种方法的问题是当前视图必须知道应用程序也会更改的视图,这对我来说似乎不是很有可扩展性。

有没有做这种事情的最佳实践?

编辑:

我应该澄清一下,这是与在应用程序中导航相关的问题。不是使用路由器的初始负载。

4

1 回答 1

1

几次面临非常接近的问题,我的解决方案如下

1) Main - html 页面中的唯一脚本,加载应用程序 + 路由器 + 控制器 1) 应用程序 - 定义根区域,启动历史记录,2) AppRouter - 监视 url 匹配并调用控制器动作 3) AppController - 保持动作哈希,连接使用自己的操作订阅事件(如 App:switchpage),管理模型和视图。

在代码中(我使用 requireJS 按需加载):

main.js

define(
    [
        'application',
        'appRouter',
        'appController'
    ], 
    function(Application, Router, Controller) {
        var App = new Application;

        App.addInitializer(function() {
            this.controller = App.Controller;
            this.router = App.Router({
                controller: this.controller
            })
        })
    }
);

应用

define(
    [
        'marionette',
        'backbone'
    ], 
    function(Marionette, Backbone) {
        return Marionette.Application.extend({
            regions: {
               'main': '#body'
            },

            onStart: function() {
                Backbone.history.start()   
            }
        })
    }
);

应用路由器

define(
    [
        'application'
    ], 
    function(Application) {

        Application.module('AppRouter', function(Module, App, Backbone, Marionette) {
            App.Router = Marionette.AppRouter.extend({
                //for example : page/home page/goods page/user
                appRouter: {
                    'page/*': 'switchPage'
                }
            })
        }) 
    }
);

应用控制器

define(
    [
        'marionette'
    ], 
    function(Marionette) {

       Application.module('AppRouter', function(Module, App, Backbone, Marionette) {
            App.Controller = Marionette.Controller.extend({
                switchPage: function(path) {
                //path (user || home || some)
                    require(['views/'+path], function(pageView) {
                        App.main.show(new pageView)
                    })
                }
            })
        })
    }
);

页面/主页

define(
    [
        'marionette',
        'underscore'
    ], 
    function(Marionette, _) {
        return Marionette.ItemView.extend({
            template: _.template("home page")
        })
    }
);

它只是一个模型,我删除了部分代码以仅保留应用程序的想法。为了使其更具可扩展性,您可以将页面定义为具有自己的控件和部门的模块。

每晚推荐您查看http://www.backbonerails.com/上的 Brian Mann 截屏视频,尤其是 工程丰富的单页应用程序 并查看 David Sulc GitHub 和项目示例

于 2014-10-30T06:21:07.540 回答