Ian*_*ait 4 jquery express handlebars.js
我正在尝试使用Express JS和Handlebars创建一个基本网站.我有两个文件,page1Router.js和page1Router.handlebars.在Handlebars文件中我有这个:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Page 1</title>
</head>
<script id="page1_template" type="text/x-handlebars-template">
<body>
{{#data.info}}
<h1>{{reportMessage 1}}</h1> <br>
{{/data.info}}
<a href="http://localhost:3030/anotherpage">Click here to go to another page.</a>
</body>
</script>
</html>
Run Code Online (Sandbox Code Playgroud)
在JS文件中我有:
var config = require("../config/config").config,
express = require("express"),
router = express.Router(),
logger = require("../logger/logger").logger,
jsdom = require("jsdom"),
$ = require('jquery')(jsdom.jsdom().createWindow()),
Handlebars = require('handlebars'),
source = $("#page1_template").html(),
template = Handlebars.compile(source);
router.get('/page1', homepage);
var data = {
info: [
{message:"Hey this is a message"},
{message:"This is a different message"},
{message:"This is a final message"}
]
};
Handlebars.registerHelper('reportMessage', function(mes) {
if (mes == 1) {
return info[0].message;
} else if (mes == 2) {
return info[1].message;
}
return "This is an error message";
});
function homepage(req, res) {
res.render(__dirname + "/page1Router.handlebars", data);
logger.info(config.Message1);
}
$('body').append(template(data));
module.exports = router;
Run Code Online (Sandbox Code Playgroud)
当我尝试使用"node app"运行服务器时,出现以下错误:
/Users/iantait/BroboticsForever/practice/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js:436
throw new Exception("You must pass a string or Handlebars AST to Handlebar
^
Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed undefined
at new Error (<anonymous>)
at Error.Exception (/Users/iantait/BroboticsForever/practice/node_modules/handlebars/dist/cjs/handlebars/exception.js:13:41)
at compile (/Users/iantait/BroboticsForever/practice/node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js:436:11)
at HandlebarsEnvironment.hb.compile (/Users/iantait/BroboticsForever/practice/node_modules/handlebars/dist/cjs/handlebars.js:19:12)
at Object.<anonymous> (/Users/iantait/BroboticsForever/practice/routers/page1Router.js:9:27)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
Run Code Online (Sandbox Code Playgroud)
我的问题是:jquery如何知道在哪里寻找"page1_template"?我相信这个错误正在发生,因为jquery没有正确找到"page1_template"脚本,但我不知道为什么.有什么建议??
看起来你正在混淆服务器端和客户端逻辑,这导致了一些问题.
最大的问题是你叫这行:
source = $("#page1_template").html()
在您实际呈现页面之前 - 实际上,您在Web应用程序启动时调用它 - 而不是在页面呈现之后.#page1_template当时您的程序没有可访问的元素,因此source可能是null或undefined.
所以回答你的问题,"jquery如何知道在哪里寻找"page1_template"?",它不知道,也无法访问它.
另一个逻辑问题是,你打电话$('body').append(template(data)); 以外的的homepage请求处理程序,这是行不通的.为了有机会工作,你必须至少把它放在请求处理程序中.
我对jsdom了解不多,但据我所知,我不认为这是你正在寻找的解决方案.没有必要在服务器端代码中使用它或jQuery.您的服务器逻辑应该能够呈现完整的页面而无需使用jQuery.
你有几个选项,都可以从服务器中杀死jsdom和jQuery.
在服务器上呈现完整页面,并res.render在homepage请求处理程序中返回结果(首选).
只需发送文件的静态部分,发出AJAX请求并使用客户端Handlebars脚本来更新页面.
切换到表达'首选的模板语言,Jade,并且除了没有额外的开销之外,就像#1一样.
还有更多,但我不会列举它们.
既然你好像喜欢使用Handlebars,我会回答#1.同样,问题的关键在于Handlebars.compile(source)线路失败,因为source它不是一个字符串,因为你试图使用jQuery从你的jsdom实例获取模板(在你的页面渲染之前就已经很久了.请记住这个JS我们写的代码存在于服务器上,而不是在浏览器中!).
第1步:获得正确的包裹
摆脱jsdom,jQuery和Handlebars,下载'express3-handlebars'(它也适用于express 4).
第2步:配置express
以下是您的快递应用程序应该是什么样子的简单外观.请特别注意我如何配置视图引擎,以便它知道如何处理.handlebars文件.
// Get the dependencies we need
var express = require('express'),
expressHbs = require('express3-handlebars');
// Create a new express app
var app = express();
// Tell express where our base directory is (for static files)
// usually, we do __dirname + '/public', so we have a public folder for public content
app.use(express.static(__dirname));
// Configure a view engine for express, so it knows how to render .handlebars files
// I set the default layout to be main.handlebars
app.engine('handlebars', expressHbs({ defaultLayout: 'main', extname: '.handlebars' }));
app.set('view engine', 'handlebars');
// Set up your route
app.get('/page1', homepage);
// Set up a request handler
function homepage(req, res) {
res.render('page1'); // We'll come back to this in a minute.
}
// Start listening
app.listen(8080);
Run Code Online (Sandbox Code Playgroud)
第3步:在正确的位置获取正确的文件
express3-handlebars在某些位置查找视图文件.它假设您有一个views/目录,其中包含views/layouts布局文件夹.
由于我们将express配置main.handlebars为我们的模板,这是我们的"主布局".它将用于每个页面,布局引擎将替换{{{body}}}为您的页面特定信息.
views/layouts/main.handlebars:
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{title}}</title>
</head>
<body>
{{{body}}}
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
同样,express3-handlebars开始在views文件夹中查找视图.无论您在页面中想要什么内容,都会在此处插入{{{body}}}.为简单起见,我没有使用你的Handlebars助手,但你当然可以这样做(阅读文档了解更多信息).但是,您确实应该尝试将逻辑保留在服务器代码中以及模板之外.
views/page1.handlebars:
<h1>{{message}}</h1>
<a href="http://localhost:3030/anotherpage">Click here to go to another page.</a>
Run Code Online (Sandbox Code Playgroud)
第4步:将它们捆绑在一起
最后,我们只需将一些数据发送到您的视图,以便正确呈现.让我们homepage从上面更新请求处理程序:
// Set up a request handler
function homepage(req, res) {
// Ideally, here is where you would determine what message to send down
var context = {
title: 'Page 1',
message: 'This is a message'
};
// Render the view in views/page1.handlebars with this data
res.render('page1', context);
}
Run Code Online (Sandbox Code Playgroud)
这应该是全部!现在,我们在将其发送到客户端之前呈现完整的HTML页面,而无需使用Handlebars模板的jQuery或JIT编译.
这是一些相关的文档:
| 归档时间: |
|
| 查看次数: |
5689 次 |
| 最近记录: |