在 AJAX 调用(使用 ExpressJS)之后,在 EJS 模板中循环遍历数组的正确方法是啥?
Posted
技术标签:
【中文标题】在 AJAX 调用(使用 ExpressJS)之后,在 EJS 模板中循环遍历数组的正确方法是啥?【英文标题】:What is the proper way to loop through an array in an EJS template after an AJAX Call (using ExpressJS)?在 AJAX 调用(使用 ExpressJS)之后,在 EJS 模板中循环遍历数组的正确方法是什么? 【发布时间】:2016-11-05 20:28:21 【问题描述】:因此,我尝试使用 request
模块/包循环访问从 http 调用中获得的对象数组到我的内部 API。到目前为止,我能够从 API 取回我的数据并在我的页面上显示完整的对象。我想在我的页面上显示它并使用 EJS 模板系统循环浏览它。我知道我可以将 AngularJS 用于前端的东西,但我想看看我只在服务器端能走多远。
下面是我的代码:
server.js
// Prepend /api to my apiRoutes
app.use('/api', require('./app/api'));
api.js
var Report = require('./models/report');
var express = require('express');
var apiRoutes = express.Router();
apiRoutes.route('/reports', isLoggedIn)
.get(function (req, res,next)
// use mongoose to get all reports in the database
Report.find(function (err, reports)
// if there is an error retrieving, send the error.
// nothing after res.send(err) will execute
if (err)
return res.send(err);
res.json(reports);
);
);
routes.js
var User = require('./models/user');
var request = require('request');
module.exports = function (app, passport)
app.get('/reports', isLoggedIn, function (req, res)
res.render('pages/new-report.ejs',
user: req.user,
title:'New Report'
);
);
request(
uri:'http://localhost:2016/api/reports',
method:'GET'
).on('data',function(data)
console.log('decoded chunk:' + data)
).on('response',function(resp)
resp.on('data', function(data)
console.log('received:' + data.length + ' bytes of compressed data');
app.get('/timeline', isLoggedIn, function (req, res)
res.render('pages/timeline',
user: req.user,
title:'Timeline',
reports: data
);
);
)
);
reports.ejs
因此,如果我只是在我的页面上像这样<p><%= reports %></p>
输出整个reports
对象,一切正常,我会得到这样的结果:
[
"_id": "5775d396077082280df0fbb1",
"author": "57582911a2761f9c77f15528",
"dateTime": "30 June 2016 - 07:18 PM",
"picture": "",
"description": "",
"location": [
-122.46596999999997,
37.784495
],
"latitude": 37.784495,
"longitude": -122.46596999999997,
"address": "4529 California St, San Francisco, CA 94118, USA",
"contact": "John Doe",
"type": "Financial",
"__v": 0,
"updated_at": "2016-07-01T02:21:10.259Z",
"created_at": "2016-07-01T02:21:10.237Z",
"tags": [
"tag1,tag2"
]
]
但是,如果我尝试循环遍历对象,如下所示,它会得到一个 UNDEFINED 作为我的 report 对象的返回属性,我显然会得到一个无限循环。
<ul class="timeline">
<% reports.forEach(function(report) %>
<li class="timeline-yellow">
<div class="timeline-time">
<span class="date" style="text-align:left">
<%= report.type %> </span>
<span class="time" style="font-weight:700;font-size:25px;line-height:20px;text-align:left;">
<%= report.dateTime %> </span>
</div>
</li>
<% ) %>
</ul>
我已经尝试了循环的另一种变体,但仍然不成功:
<ul class="timeline">
<% for (var i = 0; i < reports.length; i++) %>
<li class="timeline-yellow">
<div class="timeline-time">
<span class="date" style="text-align:left">
<%= report[i].type %>
4/10/13 </span>
<span class="time" style="font-weight:700;font-size:25px;line-height:20px;text-align:left;">
<%= report[i].dateTime %> </span>
</div>
</li>
<% %>
</ul>
【问题讨论】:
【参考方案1】:ejs
中 for
循环的语法是完美的,但迭代的数组名称是 reports 并且您似乎在迭代中使用了 report[i] ,需要将其更改为 reports[i],它应该可以工作。
reports.ejs
<ul class="timeline">
<% for (var i = 0; i < reports.length; i++) %>
<li class="timeline-yellow">
<div class="timeline-time">
<span class="date" style="text-align:left">
<%= reports[i].type %>
4/10/13 </span>
<span class="time" style="font-weight:700;font-size:25px;line-height:20px;text-align:left;">
<%= reports[i].dateTime %> </span>
</div>
</li>
<% %>
</ul>
希望这会有所帮助。
【讨论】:
【参考方案2】:I guess something like this ..
<% if (reports.length > 0)%> // Checking if there are reports
<ul class="timeline">
<% for (let report of reports) %>
<li class="timeline-yellow">
<div class="timeline-time">
<span class="date" style="text-align:left">
<%= report.type %>
4/10/13 </span>
<span class="time" style="font-weight:700;font-size:25px;line-
height:20px;text-align:left;">
<%= report.dateTime %> </span>
</div>
</li>
<% %>
</ul>
<%%>
<%%>
【讨论】:
请解释一下你的答案 基本上他会发送一个名为报告的数组作为响应。 EJS 让您可以使用 javascript 编写 - 最好看这里:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…【参考方案3】:这是我使用 loopback3 和 ejs 的工作版本:
在 server/boot/routes.js 中:
module.exports = function(app)
const router = app.loopback.Router();
router.get('/', function(req, res)
app.models.ZenGarden.find()
.then(plants =>
console.log('plants: ', plants)
res.render('index', plants:plants)
).catch(err =>
console.log('Failed to find in ZenGarden: ', err)
res.render('index')
)
);
router.post('/', function(req, res)
var plants = req.body.plants;
if (plants)
for (var i = 0; i < plants.length; i++)
console.log(plants[i])
app.models.ZenGarden.upsert(plants[i])
.then().catch(err => console.log(err))
return res.render('index', plants:plants)
)
app.use(router);
;
在服务器/views/index.ejs:
<div>
<form action='/' method='POST'>
<% if (plants) %>
<table>
<tr><td>Name</td><td>Count</td></tr>
<% for (var i = 0; i < plants.length; i++) %>
<tr>
<input type='hidden' value=<%= plants[i].id %> name='plants[<%= i %>][id]'>
<input type='hidden' value="<%= plants[i].name %>" name='plants[<%= i %>][name]'>
<td><%= plants[i].name %></td>
<td><input type='text' value=<%= plants[i].count %> name='plants[<%= i%>][count]'</td></tr>
<% %>
</table>
<button type='submit'>Save</button>
<% else %>
<p>No plant in Zen Garden :-(</p>
<% %>
</form>
</div>
确保在 server/server.js 中添加以下内容:
const path = require('path')
const bodyparser = require('body-parser')
app.set('view engine', 'ejs')
app.set('views', path.resolve(__dirname, 'views'))
app.middleware('initial', bodyparser.urlencoded(extended:true))
app.middleware('initial', bodyparser.json())
这里是ZenGarden模型的定义(common/models/zen-garden.json):
"name": "ZenGarden",
"base": "PersistedModel",
"idInjection": true,
"options":
"validateUpsert": true
,
"properties":
"name":
"type": "string",
"required": true
,
"count":
"type": "number",
"required": true
,
"validations": [],
"relations": ,
"acls": [],
"methods":
【讨论】:
以上是关于在 AJAX 调用(使用 ExpressJS)之后,在 EJS 模板中循环遍历数组的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
将视图渲染到 ExpressJS 中的变量中(用于 AJAX 响应)