Node + Express + Swig / 将本地 json 文件传递给模板
Node + Express + Swig / pass local json file to template
我是一个节点菜鸟,我能够让 express / swig 玩得很好,并在屏幕上显示,当我引入我的 d3 代码(它自己工作)时,控制台返回 Uncaught TypeError: Cannot read property 'forEach' of undefined(anonymous function) @ json:63event @ d3.js:504respond @ d3.js:1942
注意事项 - data.json
与模板位于同一目录中。
我是不是走错了路?在节点内进行 d3 渲染会更好吗?如果是这样,我该如何将其传递给 swig 模板等?
编辑 - 我注意到在开发工具中 json 没有被检索,但是 SVG 呈现。我注释掉了以下内容,因为 express 正在劫持 get。
// app.get('/*', function (req, res) {
// res.send("404 bro");
// });
现在出现了一个新的错误,这是一个好兆头!
GET http://localhost:3000/templates/data.json 404 (Not Found)
再次抱歉,我有点菜鸟。
更新 - 这是我更新的代码
var data = require('./templates/data/data.json');
console.log("====== Loaded Jason ======" + JSON.stringify(data));
app.get('/json', function(req, res){
res.render('line', {'title' : 'First Swig Template'});
res.sendFile(data);
});
返回
Unhandled rejection TypeError: undefined is not a function
更新 - 这是我更新的代码
app.get('/json', function(req, res){
res.render('line', {'title' : 'First Swig Template'});
res.sendFile('data.json', { root: path.join(__dirname, '/templates/data') });
});
返回
Error: Can't set headers after they are sent.
Json 现在显示在屏幕上。
节点代码
// Retrieve
var MongoClient = require('mongodb').MongoClient;
//Swig for template
var swig = require('swig');
//consolidate -templating consolidation library
var cons = require("consolidate");
// Express
var express = require('express');
var app = express();
app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + '/templates');
app.get('/swig', function(req, res){
res.render('home', {'title' : 'First Swig Template'});
});
app.get('/json', function(req, res){
res.render('line', {'title' : 'First Swig Template'});
});
//setup routes
app.get('/*', function (req, res) {
res.send("404 bro");
});
//setup server
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
// Connect to the db
MongoClient.connect("mongodb://localhost:27017/linejson", function(err, db) {
if(!err) {
console.log("We are connected");
}
var collection = db.collection('dummy');
// count records
collection.count(function(err, count) {
console.log("There are " + count + " records.");
});
collection.find().each(function(err, doc) {
if(doc != null) console.log("Doc from Each ");
console.dir(doc);
});
});
Html模板+D3代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Data Visualization with D3 </title>
<!-- Bootstrap CDN CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%d-%b-%y").parse;
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// Adds the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Get the data
// d3.json("data.json", function(data) {
// data.forEach(function(d) {
// d.date = parseDate(d.date);
// d.close = +d.close;
// });
d3.json("data.json", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
});
</script>
</body>
</html>
由于您使用节点来处理与服务器的交互,因此您通过节点提供了文件路径。类似下面。
app.get('/templates/data', function(req, res){
res.sendfile(data.json);
});
然后把文件放到/template/data/data.json路径下.
希望对您有所帮助。
app.use(express.static(__dirname + '/data'));
下面一行修复了它!感谢您的投入!
我是一个节点菜鸟,我能够让 express / swig 玩得很好,并在屏幕上显示,当我引入我的 d3 代码(它自己工作)时,控制台返回 Uncaught TypeError: Cannot read property 'forEach' of undefined(anonymous function) @ json:63event @ d3.js:504respond @ d3.js:1942
注意事项 - data.json
与模板位于同一目录中。
我是不是走错了路?在节点内进行 d3 渲染会更好吗?如果是这样,我该如何将其传递给 swig 模板等?
编辑 - 我注意到在开发工具中 json 没有被检索,但是 SVG 呈现。我注释掉了以下内容,因为 express 正在劫持 get。
// app.get('/*', function (req, res) {
// res.send("404 bro");
// });
现在出现了一个新的错误,这是一个好兆头!
GET http://localhost:3000/templates/data.json 404 (Not Found)
再次抱歉,我有点菜鸟。
更新 - 这是我更新的代码
var data = require('./templates/data/data.json');
console.log("====== Loaded Jason ======" + JSON.stringify(data));
app.get('/json', function(req, res){
res.render('line', {'title' : 'First Swig Template'});
res.sendFile(data);
});
返回
Unhandled rejection TypeError: undefined is not a function
更新 - 这是我更新的代码
app.get('/json', function(req, res){
res.render('line', {'title' : 'First Swig Template'});
res.sendFile('data.json', { root: path.join(__dirname, '/templates/data') });
});
返回
Error: Can't set headers after they are sent.
Json 现在显示在屏幕上。
节点代码
// Retrieve
var MongoClient = require('mongodb').MongoClient;
//Swig for template
var swig = require('swig');
//consolidate -templating consolidation library
var cons = require("consolidate");
// Express
var express = require('express');
var app = express();
app.engine('html', cons.swig);
app.set('view engine', 'html');
app.set('views', __dirname + '/templates');
app.get('/swig', function(req, res){
res.render('home', {'title' : 'First Swig Template'});
});
app.get('/json', function(req, res){
res.render('line', {'title' : 'First Swig Template'});
});
//setup routes
app.get('/*', function (req, res) {
res.send("404 bro");
});
//setup server
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
// Connect to the db
MongoClient.connect("mongodb://localhost:27017/linejson", function(err, db) {
if(!err) {
console.log("We are connected");
}
var collection = db.collection('dummy');
// count records
collection.count(function(err, count) {
console.log("There are " + count + " records.");
});
collection.find().each(function(err, doc) {
if(doc != null) console.log("Doc from Each ");
console.dir(doc);
});
});
Html模板+D3代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Data Visualization with D3 </title>
<!-- Bootstrap CDN CSS -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.js"></script>
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%d-%b-%y").parse;
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// Adds the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Get the data
// d3.json("data.json", function(data) {
// data.forEach(function(d) {
// d.date = parseDate(d.date);
// d.close = +d.close;
// });
d3.json("data.json", function(error, data) {
data.forEach(function(d) {
d.date = parseDate(d.date);
d.close = +d.close;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the valueline path.
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
});
</script>
</body>
</html>
由于您使用节点来处理与服务器的交互,因此您通过节点提供了文件路径。类似下面。
app.get('/templates/data', function(req, res){
res.sendfile(data.json);
});
然后把文件放到/template/data/data.json路径下.
希望对您有所帮助。
app.use(express.static(__dirname + '/data'));
下面一行修复了它!感谢您的投入!