EJS 内联 DOM 选择器未定义

EJS Inline DOM Selector Undefined

我正在使用 Node.js、Express、Chart.js 和 EJS 作为模板。我想要一个模板,该模板传递一个带有对象列表的变量。每个对象定义一个图表,供 Chart.js 在网页中呈现。

Chart.js 要求您将 DOM 中的 canvas 存储在您作为参数传递给 new Chart() 的变量中,但在下面的代码中,我的EJS 引用 document 时出现错误,指出它在引用它时未定义。我该如何解决这个问题?

<div class='report-content'>
    <!-- 'reportSheet' is a variable passed in from the Express route definition. -->
    <!-- for each chart object in the list of charts... -->
    <% reportSheet.forEach(function(chart){ %>
        <!-- create area for that chart -->
        <div class="chart-region">
            <div class="chart-item">
                <h3>Chart Title</h3>
                <canvas id="myChart" width="400" height="200"></canvas>
                <% var ctx = document.getElementById("myChart"); %>
                <% var myChart = new Chart(ctx, chart); %>
            </div>
        </div>
    <% }); %>
</div>

下面是根据 Chart.js 文档构建图表的示例方法:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
    // The type of chart we want to create
    type: 'line',

    // The data for our dataset
    data: {
        labels: ["January", "February", "March", "April", "May", "June", "July"],
        datasets: [{
            label: "My First dataset",
            backgroundColor: 'rgb(255, 99, 132)',
            borderColor: 'rgb(255, 99, 132)',
            data: [0, 10, 5, 2, 20, 30, 45],
        }]
    },

    // Configuration options go here
    options: {}
});
</script>

对于某些上下文:重点是让用户能够查看网页并添加新图表(如仪表板),因此数据库需要存储他们为仪表板制作的每个图表的列表。

感谢您的帮助。

好的!很头疼后终于弄明白了。我的新手水平即将显现

所以事件的顺序是这样的:

  1. 浏览器访问地址
  2. Nodejs/Express 服务器响应我的没有图表的 EJS 模板
  3. 那个 EJS 模板 运行 是一个 AJAX 脚本
  4. AJAX 脚本联系服务器以查询 MongoDB 我的图表数据
  5. 服务器从 MongoDB 检索图表数据并以 JSON 格式将其发送回 AJAX 脚本
  6. AJAX 脚本接收图表数据并使用 $ 字符串文字格式将必要的 HTML 和新脚本代码注入到第 1 步加载的页面中

相关代码如下

页面加载时没有图表。我页面的页脚调用 AJAX 脚本:

        </div>
        <script src="../../public/ajax.js"></script>
    </body>
</html>

AJAX 脚本从服务器获取图表数据并将其注入页面:

$.get("/charts", function(data){   // contacts the server route shown in code block below
    data = data[1];    // only using first chart in array of charts for now
    var chartData = JSON.stringify(data.chart); // 'data.chart' contains nested objects that describe the chart, so it must be stringified (this caused me days of headache)
    // Now inject HTML back into original page with multi-line string literal formatting. Could also use regular string concatenation.
    $(".report-content").html(
    `
        <div class="chart-region">
            <div class="chart-item">
                <h3>${data.chartName}</h3>
                <canvas id="${data._id}" width='400' height='200'></canvas>
                // script to create a chart
                <script>
                    var ctx = $("#${data._id}");
                    var chartVar = new Chart(ctx, ${chartData});
                </script>
            </div>
        </div>
    `
    );
});

服务器的 /charts 路由如下所示:

app.get("/charts", function(req, res){
    Charts.find({}, function(err, chart){
        if(err){
            console.log(err);
        } else {
            res.json(chart);
        }
    });
});

就是这样!

现在我只注入一个图表,但要加载整个图表数组,你必须摆脱 data = data[1] 和 运行 类似下面的循环(注意我还没有测试过这段代码):

$.get("/charts", function(data){    // data contains the entire array of chartContainers
    data.forEach(function(chartContainer){      // chartContainer contains a chart's data and metadata about it like a name
        var chartData = JSON.stringify(chartContainer.chart);   // chartContainer.chart contains the actual chart data that Chart.js needs
        $(".report-content").append(
        `
            <div class="chart-region">
                <div class="chart-item">
                    <h3>${chartContainer.chartName}</h3>
                    <canvas id="${chartContainer._id}" width='400' height='200'></canvas>
                    <script>
                        var ctx = $("#${chartContainer._id}");
                        var chartVar = new Chart(ctx, ${chartData});
                    </script>
                </div>
            </div>
        `
        );
    });
});