多页js应用程序的集中代码

时间:2012-12-10 18:15:46

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

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

我发现了主干,MVC模式,微模板和requirejs,但它们似乎最适合单页面应用程序。不知何故,我需要让主模块知道正在加载哪个页面,这样它就会在页面上放置正确的元素。我正在考虑传递html的标题,它将获取正确的页面元素集合并将它们作为对象传递给App.initialize。

1)任何人都可以验证这种方法吗?如果没有,建议采用其他方法吗?像木偶一样延伸骨干怎么样?

2)任何人都可以推荐一种方法将页面细节纳入骨干框架吗?

在骨干教程之后,我构建了一个成功的测试页面,其中包含一个main.js,它调用一个调用view.render方法的App.initialize方法。我的第一个想法是阅读html页面标题并使用它来为正在加载的特定页面选择一个模型。我必须传入一个具有每个页面布局细节的对象。这是视图的渲染方法,因此您可以看到我想要做的事情:

            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技能。这种语言发生了很多很酷的事情。

1 个答案:

答案 0 :(得分:1)

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

值得探索的另一个想法可能是利用Backbone.RouterpushState:true来设置正确的页面。当您在启动时拨打Backbone.history.start()时,路由器会点击与您当前网址相匹配的路线,即您所在的网页。

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

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

//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);
    }
});

处理路由器级别的视图选择:

//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});
}

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

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

(代码示例未经测试)