2017-07-31 7 views
5

Iコンドミニアムのリストをロードし、それらを表示するルートがありますKeystoneJS

app.get('/condo-list', middleware.loadCondoList, routes.views.condolist); 

loadCondoListミドルウェアはCondoBuildingモデルへの呼び出しを行います結果をres.localsに設定します。

exports.loadCondoList = function loadCondoList(req, res, next) { 

console.log('request url: ' + req.url); 
console.log('getting condo buildings...'); 

CondoBuilding.model 
    .find() 
    .exec((err, condos) => { 
     if (err) { 
      // pass error along 
      next(err); 
     } else { 
      // add CondoBuildings to locals 
      res.locals.condoBuildings = condos; 
      next(); 
     } 
    }); 
}; 

データベースへの呼び出しが成功し、ページが正常にレンダリングされます。ただし、何らかの理由でルートが2回実行されています。次のようにコンソール出力は次のとおりです。

request url: /condo-list 
getting condo buildings... 
GET /condo-list 304 344.532 ms 
request url: /condo-list 
getting condo buildings... 
GET /condo-list 304 317.631 ms 

私は複数のブラウザ(クローム、サファリ、Firefoxの)でこの動作を再現しており、これは他の路線では起こらないことを確認しました。

CondoBuilding.model.find()への呼び出しを削除し、loadCondoList()の本文にnext()を呼び出すと、この現象は発生しません。

私はそれが適切である場合には、"express": "4.14.0"

以下は、私はアプリで実行しているルートの完全なリストがあるエクスプレス4活用キーストーン4 "keystone": "4.0.0-beta.5"を実行しています:

// Setup Route Bindings 
exports = module.exports = function (app) { 

// Views 
app.get('/', routes.views.index); 
app.get('/condo-list', middleware.loadCondoList, routes.views.condolist); 
app.get('/blog/:category?', routes.views.blog); 
app.get('/blog/post/:post', routes.views.post); 
app.get('/about', routes.views.about); 
app.get('/search', middleware.getAccountType, routes.views.search); 

app.all('/contact', routes.views.contact); 

}; 

CondoListビュー:

var keystone = require('keystone'); 

exports = module.exports = function (req, res) { 

var view = new keystone.View(req, res); 
var locals = res.locals; 

// locals.section is used to set the currently selected 
// item in the header navigation. 
locals.section = 'condolist'; 

// Render the view 
view.render('condolist'); 
}; 

私はしばらくこの問題をデバッグしていましたが、私はこれを引き起こしていた可能性があるとして私の知恵の終わりです。どんな助けもありがとう。

UPDATE私は、@ phuhghのアドバイスに従い、Expressのデバッグモードでアプリケーションを実行しました。すぐに何も飛び出さなかったが、私はアプリケーションの起動時に何か変わったことに気付いた。ここで

は正常に動作準備されているいくつかのルートの配列である。ここでは

express:router:layer new/+0ms 
express:router:route new /blog/post/:post +0ms 
express:router:layer new /blog/post/:post +0ms 
express:router:route get /blog/post/:post +0ms 
express:router:layer new/+0ms 
express:router:route new /about +0ms 
express:router:layer new /about +0ms 
express:router:route get /about +0ms 
express:router:layer new/+0ms 
express:router:route new /search +1ms 
express:router:layer new /search +0ms 
express:router:route get /search +0ms 

が準備されているコンドミニアムリストルートのシーケンスです:

express:router:layer new/+0ms 
express:router:route new /condo-list +0ms 
express:router:layer new /condo-list +0ms 
express:router:route get /condo-list +0ms 
express:router:layer new/+0ms 
express:router:route get /condo-list +0ms 

お気づきのとおり、 express:router:route get /condo-list +0ms行が繰り返されます。なぜか分かりませんが、私はこの問題が私の問題に関係していると仮定しています。私はこの角度にもう少し詳しく掘り下げていますが、もう一度、この分野の知識のある方からの助けをいただければ幸いです。

アップデート2 - スタックトレース

Stack Trace

私はデバッグやステップバイスタック工程を経て行ってきました。私は機能から機能への道を歩むことができ、すべてが正常に見えるが、正常な私のベースラインは正常に機能した他のルートを見ていた。私は正直なところ、私はエクスプレスの勇気に深く関わっていたら、何を探したらいいのか分からない。スタックを通過しながら、私が作った

観察:

  • スタックトレースは正確に両方の時間/condo-listルートの実行と同じです。
  • スタックトレース(loadCondoListミドルウェアを除いたもの)は、適切に(つまり1回だけ)実行される他のルートとまったく同じです。
  • 別のルートでloadCondoListへの呼び出しを追加すると、正しく実行されます。
    • 私は​​のルート定義を次のように更新しました。app.get('/about', middleware.loadCondoList, routes.views.about);これはデータを正しくロードし、一度だけ実行されます。

私はエクスプレスlibにコードをステップ実行していますように特に注意を払うべきであるものはありますか?私はそこに私の深さのビットを感じると私は何を探すか分からない。

+1

routes.views.condolistのコードを投稿できますか? –

+0

CondoList Viewが追加されました - ミドルウェアですべての読み込みが処理されるため、何も進んでいません。 –

+1

ここに記載されているようにエクスプレスデバッグモードを有効にしてください。https://expressjs.com/en/guide/debugging.html – phuhgh

答えて

1

デバッグの日の後、私は最終的に犯人を見つけました。そして、最も恐ろしいところに隠れていました。

コンテキスト

ビューは近隣によってフィルタリングすることができるマンションの建物の石造表示をロードします。以下は、石材そのものの関連抜粋です:

<!-- Condo List Masonry --> 
<div class="condo-items"> 
{{#each condoBuildings}} 
    <div class="condo-item {{neighborhood.key}}"> 
     <div class="condo-thumb"> 
      <span class="condo-tag tag-art">{{neighborhood.name}}</span> 
      <a href="/{{condoUrl}}"><img src="{{{cloudinaryUrl image}}}" alt="{{name}}" /></a> 
     </div> 
     <div class="condo-body"> 
      <h3><a class="condo-name" href="#">{{name}}</a></h3> 
      <p>{{condoDescription}}</p> 
     </div> 
    </div> 
{{/each}} 
</div> 

問題は、この行にcloudinaryUrlヘルパーによって引き起こされた:ここでは

<a href="/{{condoUrl}}"><img src="{{{cloudinaryUrl image}}}" alt="{{name}}" /></a>

は、ヘルパーのコードです:

_helpers.cloudinaryUrl = function (context, options) { 

    // if we dont pass in a context and just kwargs 
    // then `this` refers to our default scope block and kwargs 
    // are stored in context.hash 
    if (!options && context.hasOwnProperty('hash')) { 
     // strategy is to place context kwargs into options 
     options = context; 
     // bind our default inherited scope into context 
     context = this; 
    } 

    // safe guard to ensure context is never null 
    context = context === null ? undefined : context; 

    if ((context) && (context.public_id)) { 
     options.hash.secure = keystone.get('cloudinary secure') || false; 
     var imageName = context.public_id.concat('.', context.format); 
     return cloudinary.url(imageName, options.hash); 
    } 
    else { 
     return null; 
    } 
}; 

問題

CondoBuildingモデルの中にはまだimageが定義されていないものがあります。これにより、_helpers.cloudinaryUrlメソッドのcontext引数はundefinedになります。そのような場合、ヘルパーはnullを返します。なぜこれがページのリロードにつながるのかまだ分かりませんが、これが原因だと確信しています。

修正画像はCondoBuildingモデルに存在する場合のみ<img>要素をレンダリングするためにハンドルバーテンプレートを更新

。期待通りの経路が一度だけ実行されるテンプレートへ{{#if image}}ブロックの追加により

<!-- Condo List Masonry --> 
<div class="condo-items"> 
{{#each condoBuildings}} 
    <div class="condo-item {{neighborhood.key}}"> 
     <div class="condo-thumb"> 
      <span class="condo-tag tag-art">{{neighborhood.name}}</span> 
      <a href="/{{condoUrl}}">{{#if image}}<img src="{{{cloudinaryUrl image}}}" alt="{{name}}" />{{/if}}</a> 
     </div> 
     <div class="condo-body"> 
      <h3><a class="condo-name" href="#">{{name}}</a></h3> 
      <p>{{condoDescription}}</p> 
     </div> 
    </div> 
{{/each}} 

を次のように更新されたテンプレートコードが見えます!

次のステップ

この実装に対する改良がimageが定義されていないすべてのCondoBuildingsためのプレースホルダ画像を使用することであろう。私はこの機能をまもなく追加する予定ですが、私はこの問題に対して数日前から頭を抱えていたので、答えを更新することに抵抗できませんでした。

あなたの時間と注意のおかげで皆に感謝します。

+0

うれしいです。 router:route get/condo-listはnext()を呼び出すときに問題になり、次のものは同じ(おそらくいくつかのkeystoneハンドラが後に置かれる)同じです。問題は、それが2度目にそれを登録していたことですか?私はキーストーンを推測するだろう...確かに知っているが、あなたは急いで降りて汚れていなければならないだろう。エクスプレス 'ルータはかなりシンプルですが、私はそれにブレークポイントを打ち、見つけようとします。 – phuhgh

関連する問題