Using HandlebarJS with RequireJS, ReferenceError: Handlebars is not defined
Using HandlebarJS with RequireJS, ReferenceError: Handlebars is not defined
使用 requirejs 加载 handlebarjs 时,我收到一条 ReferenceError: Handlebars is not defined
消息。
这是我在 app.js 文件中的配置
requirejs.config({
'baseUrl': 'assets/js',
'paths': {
'handlebars' : 'plugins/handlebars',
'controller' : 'controller',
'initialize' : 'initialize'
},
'shim' : {
'handlebars': {
exports: 'handlebars'
},
'controller' : {
deps: [
'handlebars'
]
}
}
});
requirejs([
'handlebars',
'initialize',
'controller'
]);
在 controller.js 文件中我有这个:
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var ihtml = template(context);
$('.testad').html(ihtml);
但是当我用这个包装上面的代码时,它似乎可以工作:
define(['handlebars'], function(Handlebars) {
// place above code here
});
但问题是,我有 define()
之外的方法无法调用。
define(['handlebars'], function(Handlebars) {
// place above code here
function handleMe() {
// some codes here
}
});
function callMe() {
handleMe();
}
另一个问题是,我有一个 initialize.js 查找属性 my-controller
并调用分配给它的函数。有点 "modularized".
define(['jquery'], function($) {
$(function() {
$('[my-controller]').each(function(e, t) {
var a = $(t).attr('my-controller');
'undefined' != typeof window[a] && $.isFunction(window[a]) ? window[a]($) : '';
});
});
所以在我的 HTML 中,如果我有 <div my-controller="callMe"></div>
,它会自动调用 callMe()
方法,它在我的 controller.js 文件中。但是将 callMe()
放在 define 中,它就不能被调用,因为它不再是全局的了。
您遇到的所有问题都与范围有关。
在您的第一个问题中,handleMe
仅作为包装它的工厂函数中的变量存在。封闭之外的任何东西都看不到它。它与此类似:
var fn = function () {
var a = 1;
};
console.log(a); // undefined
fn(); // a is set, but falls out of scope when the function returns
console.log(a); // still undefined
当您像这样在共享范围(或全局范围)中声明变量时,此 'problem' 已修复:
var a;
var fn = function () {
a = 1;
}
console.log(a); // undefined
fn(); // a is set in the parent scope
console.log(a) // 1
在第二个问题中,您尝试直接从 DOM 事件调用控制器方法,除了您尝试直接从全局范围访问方法外,您正在做同样的事情(window
).
我怀疑最好的解决方案是重新考虑如何定义和组织模块。在一个典型的 Requirejs 项目中,通常你会像这样定义你的模块:
// Controller.js
define(['handlebars'], function (handlebars) {
var Controller = function () {
// Create your controller here.
// Create any DOM elements you need here
};
Controller.prototype.initialize = function () {
// Bind the DOM events to controller methods
};
Controller.prototype.method1 = function () {};
Controller.prototype.method2 = function () {};
Controller.prototype.method3 = function () {};
return Controller
});
// main.js
require(['Controller'], function (Controller) {
var myController = new Controller();
myController.initialize();
});
使用 requirejs 加载 handlebarjs 时,我收到一条 ReferenceError: Handlebars is not defined
消息。
这是我在 app.js 文件中的配置
requirejs.config({
'baseUrl': 'assets/js',
'paths': {
'handlebars' : 'plugins/handlebars',
'controller' : 'controller',
'initialize' : 'initialize'
},
'shim' : {
'handlebars': {
exports: 'handlebars'
},
'controller' : {
deps: [
'handlebars'
]
}
}
});
requirejs([
'handlebars',
'initialize',
'controller'
]);
在 controller.js 文件中我有这个:
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var ihtml = template(context);
$('.testad').html(ihtml);
但是当我用这个包装上面的代码时,它似乎可以工作:
define(['handlebars'], function(Handlebars) {
// place above code here
});
但问题是,我有 define()
之外的方法无法调用。
define(['handlebars'], function(Handlebars) {
// place above code here
function handleMe() {
// some codes here
}
});
function callMe() {
handleMe();
}
另一个问题是,我有一个 initialize.js 查找属性 my-controller
并调用分配给它的函数。有点 "modularized".
define(['jquery'], function($) {
$(function() {
$('[my-controller]').each(function(e, t) {
var a = $(t).attr('my-controller');
'undefined' != typeof window[a] && $.isFunction(window[a]) ? window[a]($) : '';
});
});
所以在我的 HTML 中,如果我有 <div my-controller="callMe"></div>
,它会自动调用 callMe()
方法,它在我的 controller.js 文件中。但是将 callMe()
放在 define 中,它就不能被调用,因为它不再是全局的了。
您遇到的所有问题都与范围有关。
在您的第一个问题中,handleMe
仅作为包装它的工厂函数中的变量存在。封闭之外的任何东西都看不到它。它与此类似:
var fn = function () {
var a = 1;
};
console.log(a); // undefined
fn(); // a is set, but falls out of scope when the function returns
console.log(a); // still undefined
当您像这样在共享范围(或全局范围)中声明变量时,此 'problem' 已修复:
var a;
var fn = function () {
a = 1;
}
console.log(a); // undefined
fn(); // a is set in the parent scope
console.log(a) // 1
在第二个问题中,您尝试直接从 DOM 事件调用控制器方法,除了您尝试直接从全局范围访问方法外,您正在做同样的事情(window
).
我怀疑最好的解决方案是重新考虑如何定义和组织模块。在一个典型的 Requirejs 项目中,通常你会像这样定义你的模块:
// Controller.js
define(['handlebars'], function (handlebars) {
var Controller = function () {
// Create your controller here.
// Create any DOM elements you need here
};
Controller.prototype.initialize = function () {
// Bind the DOM events to controller methods
};
Controller.prototype.method1 = function () {};
Controller.prototype.method2 = function () {};
Controller.prototype.method3 = function () {};
return Controller
});
// main.js
require(['Controller'], function (Controller) {
var myController = new Controller();
myController.initialize();
});