0

最初に、mongodbデータベースから特定のマップを取得するための基本関数のshow routeを作成し(mongooseを使用)、次に.ejsテンプレートを使用してマップをクライアント側にレンダリングしました。

次に、マップをお気に入りに追加し、ユーザーのお気に入りに追加する機能を作成したいと思いました(ユーザーが独自のモデルを持っている場合)。この一環として、以下のショールートでは、ユーザーがすでにお気に入りの地図を持っている場合、表示を継続するのではなく、地図がすでにお気に入りであったことを反映するために、クライアント側で異なるコンテンツがレンダリングされるようにしたいと思いました。特定のルートをお気に入りにするオプション。

私が使おうとしている方法を以下のコードに示します。これにより、お気に入りを持つ認証済みユーザーが存在するかどうかが決まり(passport-localとそのreq.user機能を使用)、ユーザーが既にお気に入りのマップを持っている場合は、お気に入りを反復処理してさまざまな変数をレンダリングするように設計されています。

私は主に、配列内のすべてのアイテムに対してif / elseルートが呼び出され、複数のres.render呼び出しに関して競合が発生するため、問題が発生します。これは明らかに私の意図ではありません(1つしかない場合は問題なく機能します)。たとえば、配列内のアイテム)。ただし、他のルートを提供しないようにコードを修正しようとしましたが、認証されたユーザーがいるがお気に入りが存在しない場合に、個別のコンテンツをレンダリングするためのフォールスルーを処理する方法の問題が残ります。

また、部分的な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"});
                  }
    })
 };
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 に答える