根据数组迭代的结果在res.render中提供不同的内容

时间:2012-10-11 09:53:02

标签: javascript node.js express ejs

我最初创建了一个基本函数的show route,用于从mongodb数据库中获取特定的地图(使用mongoose),然后使用.ejs模板将地图渲染到客户端。

然后,我想创建一个功能来收藏地图并添加到用户的收藏夹(用户拥有自己的模型)。作为其中的一部分,在下面的节目路线中,我想确保如果用户已经在他们的收藏夹中有地图,则会在客户端呈现不同的内容以反映地图已经是最喜欢的而不是继续显示喜欢特定路线的选项。

我尝试使用的方法如下面的代码所示。这将确定是否存在具有收藏夹的authed用户(使用本地护照及其req.user功能),然后设计为迭代收藏夹并呈现不同的变量(如果用户已在其收藏夹中有地图)。

我遇到问题主要是因为if / else路由将被调用数组中的所有项目导致多个res.render调用的冲突,这显然不是我的意图(它在那里工作正常)例如,只是数组中的一个项目)。但是,我试图修改代码以不提供其他路由,但是这仍然存在如何处理直接渲染单独内容的问题,其中有一个authed用户但其收藏夹不存在。

我还尝试使用部分直通ejs-locals来迭代ejs模板本身的收藏夹,但这似乎不起作用(我怀疑上述类似的原因)。

所以我想知道的是,数组迭代方法是适当的还是可行的,还有一个更广泛的问题,即是否有更好的方法在依赖于某些服务器端变量的同一路由上显示不同的内容。

客户端代码

<div class="row">

<% if (favourite == "No") { %>
    <div class="twelvecol" id="result"><div class="textbox" id="favourite">Favourite this route</div></div>

<% } else { %>
    <div class="twelvecol" id="result"><div class="textbox">This route is in your favourites</div></div>

服务器端代码

// Locates map on basis of ID in url before returning map, stringifying and sending to server

exports.show = function(req, res) {
var mapid = req.query.id;
console.log(mapid);
Map.findOne({_id: req.query.id}, function(err, map) {

         var jmap = JSON.stringify(map);
              if (req.user && req.user.favourites.length) {
                  favarray = req.user.favourites;
                  console.log(favarray);
                  for (var i = 0; i < favarray.length; i++) {
                        var favs = favarray[i];
                        if (favs == mapid) {
                           console.log('Favourite');
                           res.render('show', {obj: jmap, user: req.user, favourite: "Yes"})
                        }
                       else (favs !== mapid) {
                            console.log("Authed user but non-favourite")
                            res.render('show', {obj: jmap, user: req.user, favourite: "No"})
                         }
                      }
                   }
            else {
                    console.log("Either non-authed user or no existing favourites")
                    res.render('show', {obj: jmap, user: req.user, favourite: "No"});
                  }
    })
 };

1 个答案:

答案 0 :(得分:1)

在传统的服务器端MVC意义上,让动作甚至视图处理模板引擎调整响应的动态部分是绝对可以的。

只要你的用户对象没有暴露给视图(作为ejs本地),你应该以你开始的方式得到你想要的东西 - 进行一些重要的修改:1。不要在循环中渲染。 (为什么?!这实际上必须导致多次渲染调用!)2。使用动作块可见的变量。 3.按照你的其他声明跳过条件! (这有效吗?!我很好奇解析器如何评估它。通常你会用else if (condition)或者使用开关来做 - 但是在你的a / b情况下你不需要它!) 。

关于更清洁代码的步骤的建议(仅限req.user案例):

var fav = false;

for (var i = 0; i < favarray.length; i++) {
  if (favarray[ i ] == mapid) {
    fav = true;
    break;
  }
}

res.render('show', {obj: jmap, user: req.user, favourite: fav})

作为一个额外的建议:使用布尔而不是像favourite这样的布尔变量的字符串,并在ejs模板中如下所示处理它们:

<% if (favourite) { %>
  ...
<% } else { %>
  ...

此外,如果用户存在且用户有喜欢的项目,您应该调整第一个if条件检查:如果要分别处理这两个条件,则不应将它们组合在一个条件语句中。