代码改变世界

前端模板文件化jQuery插件 $.loadTemplates

2013-09-08 23:14  straybird  阅读(1986)  评论(1编辑  收藏  举报

工作中使用前端模板引擎,如 artTemplate、jsRender,来替代拼接字符串。

可是直接把模板写在页面上会带来页面臃肿,模板无法重用,与 ASP.NET等后端语言语法冲突等问题。

所以将多个模板集成到一个静态文件就很有必要,同时还能利用静态文件的缓存特性。

最好还能实现按需加载,不执行渲染的话就不载入模板文件。

虽然有对应的工具可以将模板转为 javascript 代码存在 .js 文件中,但是 js 下的模板代码可读性太差,不考虑。

于是根据以上需求写了一个jQuery 插件 $.loadTemplates

(function (window, $) {
    var tplCache = {},
        ENG_JSRENDER = 'jsRender',
        ENG_ARTTEMPLATE = 'artTemplate',
        //判定使用的是哪个模板引擎
        //暂时支持jsRender 和 artTemplate
        tplEngine = ($.views && $.views.jsviews) ? ENG_JSRENDER : window.template ? ENG_ARTTEMPLATE : '',

        Template = function (tplFile, templateTag) {
            var loaded = false, callbacks = $.Callbacks(), _templates = {};

            $.ajax(tplFile).done(function (data) {
                var scripts = $(data).filter(templateTag || 'script');

                scripts.each(function () {
                    var id = this.id;
                    if (!id) return;
                    //预编译并缓存编译后的模板
                    //编译的时候要给定 id ,这样才能支持子模板嵌套
                    switch (tplEngine) {
                        case ENG_JSRENDER:
                        {
                            _templates[id] = $.templates(id, this.innerHTML).render[id];
                            break;
                        }
                        case ENG_ARTTEMPLATE:
                        {
                            _templates[id] = template.compile(id, this.innerHTML);
                            break;
                        }
                    }
                });

                loaded = true;

                //触发在文件载入完成前挂上的渲染事件
                callbacks.fire();
            });

            this.render = function (tplId, json, helper) {
                var def = $.Deferred(),
                    _render = function () {
                        var html;
                        switch (tplEngine) {
                            case ENG_JSRENDER:
                            {
                                html = $.render[tplId](json, helper);
                                break;
                            }
                            case ENG_ARTTEMPLATE:
                            {
                                if (helper) template.helper(helper);
                                html = _templates[tplId](json);
                                break;
                            }
                        }
                        def.resolve(html);
                    };

                loaded ? _render() : callbacks.add(_render);

                return def.promise();
            };

            tplCache[tplCache] = this;
        };

    $.extend({loadTemplates: function (tplFile, templateTag) {

        return tplCache[tplFile] || new Template(tplFile, templateTag);
    }});
})(window, jQuery);
$.loadTemplates 源码
var tpl = $.loadTemplates('template.html');
var json = {str:'this is test'};
var templateId = 'temp1';
tpl.render(templateId, json)
    .done(function(html){
        $('body').html(html);
    });
使用例子

存在的问题:

1. 由于使用了$.ajax 加载,所以模板文件的缓存在开发过程中可能会带来困扰。

2. 对于 'template.html' 和 './template.html' 无法识别为同一个静态文件。(前端 url 的同一性判断谁能给解下惑)