简体   繁体   English

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

[英]Centralized code for multi-page js application

I am cleaning up a multi-page app of 65+ html pages and a central javascript library. 我正在清理包含65多个html页面和中央javascript库的多页面应用程序。 My html pages have a ton of redundancies and the central js library has become spaghetti. 我的html页面有很多冗余,中央js库已变成意大利面条。 I face limitations on consolidating pages because I am working within a larger framework that enforces a certain structure. 我在合并页面时会遇到限制,因为我正在使用一个具有一定结构的更大框架。 I want to reduce the redundancies and clean up the code. 我想减少冗余并清理代码。

I discovered backbone, MVC patterns, microtemplating and requirejs, but they seem best for single page applications. 我发现了主干,MVC模式,微型模板和requirejs,但它们似乎最适合单页应用程序。 Somehow I need to let the main module know what page is being loaded so it will put the right elements on the page. 我需要以某种方式让主模块知道正在加载哪个页面,以便它将正确的元素放在页面上。 I am thinking of passing in the title of the html which will turn grab the correct collection of page elements and pass them into App.initialize as an object. 我正在考虑传递html的标题,该标题将变成获取页面元素的正确集合并将它们作为对象传递到App.initialize中。

1) Can anyone validate this approach? 1)谁能验证这种方法? If not are there alternate approaches recommended? 如果没有,建议使用替代方法吗? How about extensions to backbone like marionette? 像木偶这样的骨干网扩展怎么样?

2) Can anyone recommend a means to get page specifics into the backbone framework? 2)谁能推荐一种将页面详细信息引入主干框架的方法?

Following backbone tutorials I built a successful test page with a main.js that calls an App.initialize method that calls a view.render method. 在主干教程之后,我使用main.js调用了App.initialize方法并调用了view.render方法,构建了成功的测试页面。 My first thought is to read the html page title and use it to select a model for the specific page being loaded. 我的第一个念头是阅读html页面标题,并使用它为要加载的特定页面选择模型。 I'd have to pass in an object with the specifics for each pages layout. 我必须为每个页面布局传递一个带有详细信息的对象。 Here's the view's render method so you can see what I am trying to do: 这是视图的render方法,因此您可以看到我要执行的操作:

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

Your help will be greatly appreciated. 对你的帮助表示感谢。 I am having a lot of fun updating my circa 1999 JavaScript skills. 更新大约1999年的JavaScript技能给我带来了很多乐趣。 There's a ton of cool things happening with the language. 语言发生了很多有趣的事情。

Using the document title to choose the loaded scripts sounds a tad kludge-y. 使用文档标题来选择加载的脚本听起来有点不高兴。 If it works, though, go for it. 如果可行,那就去做。

Another idea worth exploring might be to utilize Backbone.Router with pushState:true to setup the correct page. 另一个值得探讨的想法可能是利用Backbone.RouterpushState:true来设置正确的页面。 When you call Backbone.history.start() on startup, the router hits the route that matches your current url, ie the page you are on. 当您在启动时调用Backbone.history.start()时,路由器会找到与您当前的URL(即您所在的页面)相匹配的路由。

In the route callback you could do all the page-specific initialization. 在路由回调中,您可以执行所有特定于页面的初始化。

You could move the template and container selection out of the view into the router, and set up view in the initialize() function (the view's constructor). 您可以将模板和容器选择从视图中移出到路由器中,然后在initialize()函数(视图的构造函数)中设置视图。 Say, something like: 说,类似:

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

Handle the view selection at the router level: 在路由器级别处理视图选择:

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

And kick off the application using Backbone.history.start() 并使用Backbone.history.start()启动应用程序

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

In this type of solution the view code doesn't need to know about other views' specific code, and if you need to create more specialized view classes for some pages, you don't need to modify original code. 在这种解决方案中,视图代码不需要了解其他视图的特定代码,并且如果您需要为某些页面创建更专业的视图类,则无需修改原始代码。

At a glance this seems like a clean solution. 乍一看,这似乎是一个干净的解决方案。 There might of course be some issues when the router wants to start catching routes, and you want the browser to navigate off the page normally. 当路由器想要开始捕获路由,并且您希望浏览器正常浏览页面时,当然可能会有一些问题。 If this causes serious issues, or leads to even bigger kludge than the title-based solution, the original solution might still be preferrable. 如果这引起了严重的问题,或者导致比基于标题的解决方案更大的麻烦,那么原始解决方案可能仍然是更可取的。

(Code examples untested) (代码示例未经测试)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM