javascript - 多页面js应用的集中代码

标签 javascript model-view-controller backbone.js multipage

我正在清理一个包含 65 个以上 html 页面和中央 javascript 库的多页面应用程序。我的 html 页面有大量冗余,中央 js 库已成为意大利面条。我在合并页面方面面临限制,因为我在一个强制执行特定结构的更大框架内工作。我想减少冗余并清理代码。

我发现了主干、MVC 模式、微模板和 requirejs,但它们似乎最适合单页应用程序。我需要以某种方式让主模块知道正在加载哪个页面,以便它将正确的元素放在页面上。我正在考虑传递 html 的标题,这将转而获取页面元素的正确集合并将它们作为对象传递到 App.initialize 中。

1) 任何人都可以验证这种方法吗?如果没有,是否有推荐的替代方法?像牵线木偶这样的 Backbone 扩展怎么样?

2) 谁能推荐一种将页面细节纳入主干框架的方法?

按照主干教程,我使用调用 App.initialize 方法的 main.js 构建了一个成功的测试页面,该方法调用了 view.render 方法。我的第一个想法是阅读 html 页面标题并使用它来为正在加载的特定页面选择模型。我必须传入一个对象,其中包含每个页面布局的细节。这是 View 的呈现方法,因此您可以看到我正在尝试做什么:

            render: function () {  // pass parameter to render function here?
            var data = new InputModel,
                pageTitle = data.pageTitle || data.defaults.pageTitle,
                compiled,
                template;

            var pageElements = [
                { container: '#page_title_container', template: '#input_title_template' },
                { container: '#behavior_controls_container', template: '#behavior_controls_template' },
                { container: '#occurred_date_time_container', template: '#date_time_template' }]

            for (var i = 0; i < pageElements.length; i++) {
                this.el = pageElements[i].container;
                compiled = _.template($(InputPageTemplates).filter(pageElements[i].template).html());
                template = compiled({ pageTitle: pageTitle });  
                //pass in object with values for the template and plug in here?
                $(this.el).html(template);
            }
        }

非常感谢您的帮助。我在更新大约 1999 年的 JavaScript 技能时玩得很开心。这门语言发生了很多很酷的事情。

最佳答案

使用文档标题来选择加载的脚本听起来有点笨拙。不过,如果它有效,那就去做吧。

另一个值得探索的想法可能是利用 Backbone.Router使用 pushState:true 设置正确的页面。当您在启动时调用 Backbone.history.start() 时,路由器会命中与您当前 url 匹配的路由,即您所在的页面。

在路由回调中,您可以进行所有特定于页面的初始化。

您可以将模板和容器选择从 View 中移到路由器中,并在 initialize() 函数( View 的构造函数)中设置 View 。比如说:

//view
var PageView = Backbone.View.extend({
    initialize: function(options) {
        this.model = options.model;
        this.el = options.el;
        this.title = options.title;
        this.template = _.template($(options.containerSelector));
    },

    render: function() { 
        window.document.title = title;
        var html = this.template(this.model.toJSON());
        this.$el.html(html);
    }
});

在路由器级别处理 View 选择:

//router
var PageRouter = Backbone.Router.extend({
    routes: {
        "some/url/:id": "somePage",
        "other/url":    "otherPage"
    },

    _createView: function(model, title, container, template) { 
        var view = new PageView({
            model:model,
            title:title
            el:container,
            templateSelector:template,
        });
        view.render();
    },

    somePage: function(id) { 

        var model = new SomeModel({id:id});
        this._createView(model, "Some page", "#somecontainer", "#sometemplate");
    },

    otherPage: function() {
        var model = new OtherModel();
        this._createView(model, "Other page", "#othercontainer", "#othertemplate");
    }
});

然后使用 Backbone.history.start() 启动应用程序

//start app
$(function() {
    var router = new PageRouter();
    Backbone.history.start({pushState:true});
}

在这种类型的解决方案中, View 代码不需要知道其他 View 的具体代码,如果您需要为某些页面创建更专业的 View 类,则不需要修改原始代码。

乍一看,这似乎是一个干净的解决方案。当路由器想要开始捕获路由并且您希望浏览器正常导航到页面之外时,当然可能会出现一些问题。如果这会导致严重的问题,或者导致比基于标题的解决方案更大的问题,那么原始解决方案可能仍然更可取。

(代码示例未经测试)

关于javascript - 多页面js应用的集中代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13806737/

相关文章:

javascript - Jquery 附加 <tr> 到表意外关闭 <tr> 标签

java - 需要一本书来逐步学习使用Servlet/jsp|JSTL|EL等进行MVC购物车开发

php - 何时在 Zend Framework 中使用模块?

javascript - Marionette 2.0 ViewDestroyedError : Cannot use a view thats already been destroyed

backbone.js - 值不改变时触发 Backbone .js改变

javascript - 按参数排序

javascript - youtube 数据 api 和 node.js 错误 : Required parameter: part

javascript - 将 JSON 嵌套到平面 HTML 表

model-view-controller - 从 Grails 中的布局 View 访问模型

javascript - 如何销毁BackboneFactory中创建的对象以及它们存储在哪里?