Backbone.js 将doT.js与require.js一起使用

Backbone.js 将doT.js与require.js一起使用,backbone.js,requirejs,Backbone.js,Requirejs,我在这里使用一个身份验证示例,而不是使用下划线模板,我想使用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.1

我在这里使用一个身份验证示例,而不是使用下划线模板,我想使用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.
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;

});
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;
});
我的app.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.
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;

});
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;
});
当我加载页面时,我得到了错误

未捕获引用错误:未定义点

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

查看源代码,我发现它自己调用了
define
。因此,您不需要为其配置
垫片。为调用
define
的模块提供
shim
,可能会混淆RequireJS

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

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

这起作用了。我删除了垫片,并在define和函数中添加了点,它呈现了。你怎么知道doT检测它是否在AMD环境中?它是在文档中说的还是在代码中的某个地方?这是构建web应用程序的正确方法吗?仅在需要的地方定义点?检查非常简单。您要做的是在源代码中搜索
define(
)。如果您找到它,模块很有可能是AMD感知的。但是,它可能只是一个
define(
函数,与AMD无关。因此,您可以在
define之前进行检查(
调用测试
define
是函数且
define.amd
是真实值的代码,因为这是检测您是否在amd兼容环境中运行的方法。