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'));

下面一行修复了它!感谢您的投入!