代码之家  ›  专栏  ›  技术社区  ›  billy

nodejs api:如何渲染.pug并同时发送Ajax响应?

  •  0
  • billy  · 技术社区  · 6 年前

    我正在尝试使用来自Web服务器的数据通过 fetch() 请求例如

    res.send({myData: data});
    

    问题是: res.send() 删除浏览器上的PUG模板。填充图表的最佳方法是什么 取() 在屏幕上呈现模板时响应?

    index.js-节点API

    var express = require('express');
    var router = express.Router();
    
    /* GET home page. */
    router.get('/', function(req, res, next) {
    
      res.render('index', { title: 'Express' });
    });
    
    router.post('/', function(req, res, next) {
      if(req.body.name) {
        console.log(req.body.name);
        data = [100, 200, 150, 100];
      } else {
        data = [0, 0, 0, 0];
      }
    
      res.send({myData: data});
      // res.render('index', { graph_data: data });
    
    });
    
    
    
    module.exports = router;
    

    myscript.js-带Ajax请求的客户端脚本

    // make an ajax fetch request to the server for graph data and populate it.
    document.getElementById("form").addEventListener("submit", function(event) {
    
        // get for inputs to send to server
        let name = document.getElementById("form-name").value;
        console.log("fetch...");
    
        // event.defaultPrevented();    
        // give endpoint, and create a request to send
        fetch("/", {
            method: 'POST',
            headers: new Headers(),
            body: JSON.stringify({ name: name})
        }).then(function(response) {
                console.log("response returned..")
                return response.json();
            }).then(function(myJson) {
                console.log("populated data.")
                populateGraph(myJson);
        });
    
    });
    
    console.log("populated data.")
    
    
    
    var ctx = document.getElementById("myChart");
    
    function populateGraph(myJson) {
        var myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
                datasets: [{
                    label: '# of Votes',
                    data: [0, 0, 0],
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(255, 206, 86, 0.2)',
                        'rgba(75, 192, 192, 0.2)',
                        'rgba(153, 102, 255, 0.2)',
                        'rgba(255, 159, 64, 0.2)'
                    ],
                    borderColor: [
                        'rgba(255,99,132,1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(255, 206, 86, 1)',
                        'rgba(75, 192, 192, 1)',
                        'rgba(153, 102, 255, 1)',
                        'rgba(255, 159, 64, 1)'
                    ],
                    borderWidth: 1
                }]
            },
            options: {
                responsive:true,
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero:true
                        }
                    }]
                }
            }
        });
    
        myChart.data.datasets[0].data.push(myJson.myData);
        myChart.update();
    
    
    }
    

    有什么关于如何使这个工作的想法吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   rufus1530    6 年前

    我看不到服务器实际呈现的代码,但是如果您的表单包含action属性,那么您需要防止提交时的默认行为。为此,请修改“提交”事件侦听器回调:

    document.getElementById("form").addEventListener("submit", function(event) {
        event.preventDefault(); // don't execute default browser's behaviour
    
        // rest of your code goes here
    });
    

    现在,图表不更新的原因可能有很多。对于初学者,不要在节点API中使用res.send(),而是使用 JSON() -这样,您的服务器将以JSON格式发送数据。另外,我会移动这条线…

    var ctx = document.getElementById("myChart");
    

    …到Populategraph函数,使其自给自足。

    最后,记住使用

    myChart.data.datasets[0].data.push(myJson.myData);
    

    实际上,您正在向数据集的数据数组添加值。因此图表上标签的值为:

    Red: 0
    Blue: 0
    Yellow: 0
    Green: 100
    Purple: 200
    Orange: 150
    

    最后一个数字(100)将不会分配给任何标签。

    另一方面,应该使用POST请求为服务器发送数据,而不是获取数据。我知道您可能只是在尝试Express,但是在设计API时,它应该作为对GET请求的响应来提供数据。

    对于将来,最好将呈现页面的服务器和API分开。

        2
  •  0
  •   Anton Pastukhov    6 年前

    您可以有两个单独的JSON后端端点和一个常规模板,也可以在客户端发送“content-type”:“application/json”头文件。 fetch 然后在服务器端代码中检查这个头。如果存在头,则可以使用 res.json() 相反,如果 res.send()