【问题标题】:Using doT.js with require.js将 doT.js 与 require.js 一起使用
【发布时间】:2014-04-05 16:38:31
【问题描述】:

我正在使用来自https://github.com/alexanderscott/backbone-login 的身份验证示例,而不是使用下划线模板,我想使用 doT.js 模板。

我已将 doT.js 源添加到 lib 目录,我的 config.js 看起来像这样

if (typeof DEBUG === 'undefined') DEBUG = true;

require.config({

    baseUrl: '/assets',

    paths: {

        //'jquery'            : 'http://code.jquery.com/jquery-1.10.2.js',
        'jquery'              : 'assets/lib/jquery',
        'underscore'            : 'assets/lib/underscore',         // load lodash instead of underscore (faster + bugfixes)

        'backbone'              : 'assets/lib/backbone',
        'bootstrap'             : 'assets/vendor/bootstrap/js/bootstrap',
        'doT'                   : 'assets/lib/doT',
        'text'                  : 'assets/lib/text',
        'parsley'               : 'assets/lib/parsley'

    },

    // non-AMD lib
    shim: {
        //'jquery'                : { exports  : '$' },
        'underscore'            : { exports  : '_' },
        'backbone'              : { deps : ['underscore', 'jquery'], exports : 'Backbone' },
        'bootstrap'             : { deps : ['jquery'], exports : 'Bootstrap' },
        'parsley'               : { deps: ['jquery'] },
        'doT'                   : { exports : 'doT'}

    }

});

require(['main']);           // Initialize the application with the main application file.

我的 app.js 看起来像这样

define([
    "jquery",
    "underscore",
    "backbone",
    "doT",
    "utils"

],
function($, _, Backbone, doT) {

    var app = {
        root : "/",                     // The root path to run the application through.
        URL : "/",                      // Base application URL
        API : "/api",                   // Base API URL (used by models & collections)

        // Show alert classes and hide after specified timeout
        showAlert: function(title, text, klass) {
            $("#header-alert").removeClass("alert-error alert-warning alert-success alert-info");
            $("#header-alert").addClass(klass);
            $("#header-alert").html('<button class="close" data-dismiss="alert">×</button><strong>' + title + '</strong> ' + text);
            $("#header-alert").show('fast');
            setTimeout(function() {
                $("#header-alert").hide();
            }, 7000 );
        }
    };

    $.ajaxSetup({ cache: false });          // force ajax call on all browsers

    //alert(doT.template("what up {{=it.name}}"),{'name': 'John'});
    // Global event aggregator
    app.eventAggregator = _.extend({}, Backbone.Events);

    return app;

});

HeaderView.js 看起来像这样

define([
    "app",
    "text!templates/header.html",
    "utils",
    "bootstrap"
], function(app, HeaderTpl){

    var HeaderView = Backbone.View.extend({

        template: doT.template(HeaderTpl), //_.template(HeaderTpl),

        initialize: function () {
            _.bindAll(this);

            // Listen for session logged_in state changes and re-render
            app.session.on("change:logged_in", this.onLoginStatusChange);
        },

        events: {
            "click #logout-link" : "onLogoutClick",
            "click #remove-account-link" : "onRemoveAccountClick"
        },

        onLoginStatusChange: function(evt){
            this.render();
            if(app.session.get("logged_in")) app.showAlert("Success!", "Logged in as "+app.session.user.get("username"), "alert-success");
            else app.showAlert("See ya!", "Logged out successfully", "alert-success");
        },

        onLogoutClick: function(evt) {
            evt.preventDefault();
            app.session.logout({});  // No callbacks needed b/c of session event listening
        },

        onRemoveAccountClick: function(evt){
            evt.preventDefault();
            app.session.removeAccount({});
        },


        render: function () {
            if(DEBUG) console.log("RENDER::", app.session.user.toJSON(), app.session.toJSON());
            this.$el.html(this.template({ 
                logged_in: app.session.get("logged_in"),
                user: app.session.user.toJSON() 
            }));
            return this;
        },

    });

    return HeaderView;
});

当我加载页面时出现错误

Uncaught ReferenceError: doT is not defined

我可以在 app.js 文件中调用 doT.template() 函数,我可以看到 doT.js 已加载到我的网络选项卡中,但是当我尝试在 HeaderView.js 中使用它时,我不断收到错误消息.我是 require.js 的新手,所以我确定我误解了它的工作原理。

【问题讨论】:

    标签: backbone.js requirejs


    【解决方案1】:

    查看doT 的来源,我看到它自己调用了define。所以你不需要为它配置shim。为调用define 的模块提供shim 会混淆RequireJS。

    此外,在这里的案例中,我看到如果 doT 检测到它是 AMD 环境(RequireJS 是),那么它确实在全局空间中将自己定义为 @987654326 @。因此,您的 HeaderView.js 文件必须在所需模块中包含 doT。比如:

    define([
        "app",
        "text!templates/header.html",
        "doT",
        "utils",
        "bootstrap"
    ], function(app, HeaderTpl, doT){
    

    【讨论】:

    • 这行得通。我删除了 shim 并将 doT 添加到定义和函数中并呈现。你怎么知道 doT 检测它是否在 AMD 环境中?它是在文档中说还是在代码中的某个地方?这是构建仅在我需要的地方定义 doT 的 Web 应用程序的正确方法吗?
    • 检查非常简单。你要做的是在源代码中搜索define(。如果您找到它,那么该模块很有可能是 AMD 感知的。但是,它可能只是一个与 AMD 无关的 define( 函数。因此,您在define( 调用之前检查测试define 是一个函数并且define.amd 是一个真实值的代码,因为这是检测您在AMD 兼容环境中运行的方法。
    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 1970-01-01
    • 2013-04-16
    • 2012-09-13
    相关资源
    最近更新 更多