【问题标题】:Providing different content in res.render dependent on results of array iteration根据数组迭代的结果在 res.render 中提供不同的内容
【发布时间】:2012-10-11 09:53:02
【问题描述】:

我最初为一个基本功能创建了一个显示路线,以从 mongodb 数据库(使用 mongoose)获取特定地图,然后使用 .ejs 模板将地图渲染到客户端。

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

我一直在尝试使用的方法如下面的代码所示。这将确定是否存在具有收藏夹的经过身份验证的用户(使用 passport-local 及其 req.user 功能),然后设计为迭代收藏夹并在用户收藏夹中已有地图时呈现不同的变量。

我遇到问题主要是因为将为数组中的所有项目调用 if/else 路由,从而导致多个 res.render 调用发生冲突,这显然不是我的意图(它在哪里可以正常工作例如,只是数组中的一项)。但是,我试图修改代码以不提供其他路线,但这仍然留下了如何处理失败以呈现单独内容的问题,其中存在经过身份验证的用户但其收藏夹不存在。

我还尝试通过 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"});
                  }
    })
 };

【问题讨论】:

    标签: javascript node.js express ejs


    【解决方案1】:

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

    只要您的用户对象不暴露给视图(作为 ejs 本地),您应该以您开始的方式获得您想要的 - 进行一些重要的修改: 1. 不要在循环内渲染。 (为什么?!这实际上必须导致多次渲染调用!) 2. 使用对动作块可见的变量。 3. 跳过 else 语句后面的条件! (这行得通?!我很好奇解析器是如何评估它的。通常你会用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})
    

    作为附加建议:使用 booleans 而不是字符串作为布尔变量,如 favourite,并在您的 ejs 模板中按如下所示处理它们:

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-23
      • 2017-04-15
      • 1970-01-01
      • 2011-03-09
      • 2019-05-22
      • 2022-01-21
      • 2019-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多