0

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

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

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

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

我还尝试通过 ejs-locals 使用 partial 来迭代 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"});
                  }
    })
 };
4

1 回答 1

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})

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

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

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

于 2012-10-11T18:17:16.977 回答