2016-07-14 92 views
0

我在我的MEAN應用程序中模板緩存存在一些問題。我有一個導航欄使用條件邏輯來顯示/隱藏顯示給用戶的按鈕。當用戶點擊該頁面時,這些值將被設置爲null或false,但是一旦他們登錄,這些值將會改變(視圖,isLoggedIn)模板緩存ExpressJS

我的問題是這樣的 - 當我第一次點擊該頁面時,值如預期那樣設置爲空/假,並且按鈕被隱藏。

但是,成功登錄後,角度登錄控制器將通過$location.path("/pathAfterLogin");進行重定向,並將用戶置於正確的狀態,但使用隱藏的按鈕。只有在我進行硬刷新(control-f5)後,頁面纔會刷新並根據app.js文件中設置的值顯示相應的按鈕。

我使用的是Angular 1.5,UI-Router,Express 4Swig templatesconsolidate模板引擎。 NODE.ENV將開發。

我也嘗試禁用緩存每一個我能想到的地方。

我app.js文件看起來像這樣:

'use strict'; 

var express = require('express'), 
    path = require('path'), 
    cons = require('consolidate'), 
    swig = require('swig'); 


module.exports = function() { 
    var app = express(); //start an express app app.disable('view cache'); 

    app.engine('html', cons.swig); 

    app.set('view engine', 'html'); 
    app.set('views',path.join(__dirname,'../app/views')); 
    app.set('view cache', false); //set cache 

    swig.setDefaults({ cache: false }); 

    app.get('*', stuff.test, function(req, res, next) { 
     res.setHeader('Cache-Control', 'no-cache'); 
     res.render('index', { 
      cache: false, 
      views: req.views, 
      isLoggedIn: req.isLoggedIn 
     }); 
    }); 
     return app; 
}; 

HTML文件是我的主要佈局/視圖,因爲這是與URL重新改寫打開一個單頁的應用程序。下面的index.html文件是,包括也是一個導航文件。

<!doctype html> 
<html ng-app="myapp" ng-cloak xmlns="http://www.w3.org/1999/html"> 
<head> 
    <base href="/" /> 
    (truncated ...) 
</head> 

<body> 
<header>{% include "../../public/templates/header.html" %}</header> 
<header>{% include "../../public/templates/navigation.html" %}</header> 
<div class="res whitespace"> 

     <ui-view/> 
</div> 

</body> 
<script src = "angular.js"></script> 
<script src = "loginCtrl.js"></script> 
<script src = "loginSrvc.js"></script> 
</html> 

附送導航文件:

<div id="subtitle"> 
    <ul class="nav nav-pills pull-right"> 
     {% if !isLoggedIn %}<li ui-sref-active="active"><a ui-sref="login">Login</a></li>{% endif %} 
     {% if isLoggedIn %}<li ui-sref-active="active"><a ui-sref="logout">Logout</a></li>{% endif %} 
     {% for item in views %} 
      {% if item == "linkA" %}<li ui-sref-active="active"><a ui-sref="linkA">LinkA</a></li>{% endif %} 
      {% if item == "LinkB" %}<li ui-sref-active="active"><a ui-sref="linkB">LinkB</a></li> {% endif %} 
     {% endfor %} 
     {% if !isLoggedIn %}<li ui-sref-active="active"><a ui-sref="info">Info </a></li>{% endif %} 
     <li class="dropdown"ui-sref-active="active"> 
      {% for item in views %} 
       {% if resource == "mainDD" %} <a class="dropdown-toggle" data-toggle="dropdown" href="#"> Drop Downs <span class="caret"></span></a> 
        <ul class="dropdown-menu"> 
        {% for item in permissions %} 
         {% if item == "link1" %}<li><a ui-sref="link1">Link 1</a></li>{% endif %} 
         {% if item == "link2" %}<li><a ui-sref="link2">Link 2</a></li>{% endif %} 
         {% endfor %} 
        </ul> 
       {% endif %} 
      {% endfor %} 
     </li> 
    </ 

ul>

我有2個問題:

  1. 是緩存適當關閉?如果不是,我會在哪裏出錯?
  2. 緩存關閉時這是預期的行爲嗎?
+0

你到底是如何登錄的?你說的是_「在成功登錄後,角度登錄控制器通過'$ location.path(」/ pathAfterLogin「)''_進行重定向,這聽起來就像通過AJAX調用登錄一樣。這通常不會觸發服務器端模板的完全重新渲染。 – robertklep

+0

正確。我使用$ http.post(來自Angular)將用戶憑證提交給Node服務器,然後在用戶登錄時返回true/false值。我需要做些什麼才能觸發完整的重新呈現服務器端模板的? –

回答

0

的問題是,你混合後端模板與前端路由:

{% if isLoggedIn %}<li ui-sref-active="active"><a ui-sref="logout">Logout</a></li>{% endif %} 

isLoggedIn是用於確定其內容(<li>)應顯示在服務器端變量生成的HTML。

如果用戶在生成HTML時未登錄,則只有完整的(服務器端)模板重新呈現將導致「註銷」按鈕出現在獲取HTML的HTML中送達瀏覽器。

要解決此問題,您需要重新加載頁面(我在很長一段時間內沒有使用Angular,但$window.location.reload()用於工作),因此服務器有機會提供更新的HTML。

另外,也可以考慮是否要顯示特定頁面元素角移動模板的邏輯:

<li ng-if="loggedIn" ui-sref-active="active"><a ui-sref="logout">Logout</a></li> 

(其中loggedIn是在控制器變量)

要明確:這與緩存無關。 Express中的視圖緩存不會緩存渲染模板(即HTML),但已編譯模板(通常,必須從文件中讀取模板,進行處理或「編譯」,然後準備好用於渲染)。

+0

另一種方法是我首先考慮的,但是,它允許用戶看到他們可以或不可以執行的按鈕和動作,因爲角度邊仍然顯示HTML。快遞模板沒有。 Windows.location.reload將重新加載狀態,但我想同時重新下載HTML和重定向。我不確定這是否會允許這兩種行動。 –

+1

嘗試使用'$ window.location.href ='/ pathAfterLogin''而不是使用'$ location'。 – robertklep