模板中的全局变量

时间:2015-06-22 19:08:48

标签: javascript backbone.js ejs

我有这个EJS模板代表我的Web应用程序的标题。我试图访问我在前端Backbone应用程序中定义的全局变量,但由于某种原因,我收到一条错误,说“appGlobal未定义”。我的前端JavaScript中的全局变量如下:

appGlobal = {

        authorized: null,
        currentUser: null,
        env: null

    };

模板如下所示:

<header>
    <div>
        <div id="header-div-id">
            <% if(appGlobal && appGlobal.currentUser != null) { %>
            <div>Logged In As: <%= appGlobal.currentUser%></div>
            <button id="logout-button-id">Logout</button>
            <% } else { %>
            <div>You need to either register or login.</div>
            <% } %>
        </div>
    </div>
</header>
  1. 我相信appGlobal未在模板中定义的原因
    是因为模板是服务器端而不是客户端; 和appGlobal是全球客户。
  2. 但是,这段代码仍然应该检查是否定义了appGlobal,所以我不明白它为什么会抛出错误???
  3. 如果我更改模板以使用window.appGlobal,则窗口不是 定义
  4. 所以看起来确实模板是在服务器端呈现的 - 移动它以使其呈现客户端的最佳方式是什么?标头模板包含在index.ejs文件中,如下所示:

    <% include ./partials/header %>
    
    <main>
        <h1><%= title %></h1>
        <p>Welcome to <%= title %></p>
        <div name="main-div" id="main-div-id">
        </div>
    </main>
    
    <% include ./partials/footer %>
    

2 个答案:

答案 0 :(得分:3)

您正在使用的模板系统(EJS)在服务器端执行,并且不知道与客户端代码相关的语义。

在这种情况下,appGlobal变量声明永远不会被EJS评估,因此无法通过服务器端作用域访问。

答案 1 :(得分:1)

  
      
  1. 我认为appGlobal未在模板中定义的原因   是因为模板是服务器端而不是客户端;和appGlobal是一个全球化的客户。
  2.   

这完全正确;您发送到浏览器的任何代码(HTML,CSS,JS)都不会被服务器以任何方式解析:服务器将该代码视为文本。在编译服务器端模板时,尚未在浏览器中运行的任何JavaScript都已运行。

  
      
  1. 但是,此代码仍应检查appGlobal是否已定义,因此我不明白它为什么会抛出错误???
  2.   

嗯,确实如此,但appGlobal未在服务器上定义,因为代码不在服务器上运行。它只在客户端上运行。

  
      
  1. 如果我更改模板以使用window.appGlobal,则不定义窗口
  2.   

由于同样的原因,没有定义。

一种可能的解决方案是为了在服务器上安装appGlobal变量,然后使用EJS将其添加到客户端代码中。例如,在服务器代码中的某个位置,您可能有类似这样的内容:

ejs.render(templateStr, { data: 'here' });

(如果您使用像Express这样的库,可能会有点不同。)

如果您在服务器上创建appGlobal,则可以将其作为参数添加到数据对象中,并在模板中根据需要使用它:

var appGlobal = {
    authorized: null,
    currentUser: null,
    env: null
};
ejs.render(templateStr, { appGlobal: appGlobal });

但是,如果您想在客户端提供此变量,您可以对其进行字符串化并将其添加到模板中。所以JavaScript看起来像这样:

ejs.render(templateStr, { 
    appGlobal: appGlobal,
    appGlobalStr: JSON.stringify(appGlobal)
});

然后在您的模板中,您可以执行以下操作:

<script>
    var appGlobal = <%- appGlobalStr %>;
</script>

注意使用<%- %>分隔符,用于非转义输出。

实现非常重要,这意味着客户端最初会获得服务器appGlobal变量的当前值,但不会保留#&strong# 34;同步&#34;一点都不此外,请确保客户端可以访问appGlobal对象的所有属性。例如,如果您使用用户记录执行此类操作,则您绝对不希望将passwordHash(以及许多其他属性)发送到客户端。