【问题标题】:Where should I define JS function to call in EJS template我应该在哪里定义要在 EJS 模板中调用的 JS 函数
【发布时间】:2015-08-12 15:48:04
【问题描述】:

我正在开发一个模板,我正在尝试使用 express 和 ejs 呈现模板。至于节点应用程序的标准结构,我有 app.js 文件,其中包含以下功能:

app.locals.getFlag = function(country) {
var flag_img_name = "";
if (country.toLowerCase() == "us") {
    flag_img_name = "flag_us16x13.gif";
}   
else if (country.toLowerCase() == "ca"){
    flag_img_name = "flag_ca16x13.gif";
}
return flag_img_name;
}

我有 some_template.ejs 文件,它调用这个函数如下:

<img src="http://some_url_path/<%=getFlag(data_point[0].country_name) %>" width="16" height="14" alt="country" >

它工作得很好。但是,我有大约 15-20 个这样的函数,我不想在 app.js 中定义所有这些函数。还有其他地方可以定义这些函数并以与我现在相同的方式在模板中调用它们吗?如果是,那么定义它们的方式是什么,以便它们像现在一样可以访问。

我是 node、express 和 ejs 的新手,不确定不同的技术。如果有人能照亮它,那就太好了。提前谢谢你。

【问题讨论】:

    标签: node.js express ejs


    【解决方案1】:

    仅在此处发布此答案,以供在解决同一问题时可能最终解决此问题的人。

    您所要做的就是创建新文件(例如functions.ejs)并将其包含在您要调用该函数的 .ejs 文件中。所以,我在名为 functions.ejs 的文件中有这样的功能:

    <%
    getPriceChgArrow = function(value) {
        arrow_img_name = "";
        if (value < 0) {
            arrow_img_name = "arrow_down12x13.gif";
        }
        else {
            arrow_img_name = "arrow_up12x13.gif";
        }
        return arrow_img_name;
    }
    %>
    

    然后将functions.ejs 包含到您要从中调用函数的文件中。说,我想在quote.ejs 文件中调用这个函数。因此,我将其包括如下:

    <% include *file_path*/functions %> 
    

    只需在您要调用它的 ejs 文件中的适当位置使用此函数。例如:

    <img src = "http:/some_url/<% getPriceChgArrow(data_point[0].value) %>" />
    

    一切就绪。希望这对某人有所帮助。

    【讨论】:

    • 我得到 function_name is not defined 有什么想法吗?
    • 你的函数是否在你定义的文件中的开始和结束标签()中?
    • 它对我也不起作用,但以that 的方式起作用。
    • 我可以直接从js调用这个&lt;img src = "http:/some_url/&lt;% getPriceChgArrow(data_point[0].value) %&gt;" /&gt;吗?
    • 祝您测试成功!我认为 Faaiq 的答案应该是公认的。
    【解决方案2】:

    好吧,由于某种原因,我接受的答案对我来说并不奏效。此外,为我的每个函数创建一个单独的 *.ejs 文件然后在视图中导入该文件是没有意义的 - 特别是当我要实现非常简单的逻辑时。

    其实定义函数并在视图中使用非常简单易行

    我这样做了:

    <%
       // ------ Define a function
       get_tree = function(tree){
          for(var i in tree){
    %>
         <%= tree[i].title %>
    <%
          }
       }
      // ----- Call the above declared function
      get_tree(tree);
    %>
    

    它有效!

    谢谢

    【讨论】:

    • 是的,你的方法也很有意义。我创建单独的 functions.ejs 文件的唯一原因是因为我想将所有函数放在一起。我在下面展示的只是我在整个应用程序中使用的众多功能之一。
    • 好吧,我明白了,但首先,在“视图”上有逻辑并不是一个好习惯,当然也有例外,但是,所有的计算和计算都应该在逻辑方面实现,一旦完成,然后将其发送到“渲染”视图。
    【解决方案3】:

    似乎最简单的方法是将附加到对象的函数与渲染的所有数据一起传递:

    在你的 js 中:

    const data = {
      ...all other data,
      getFlags: function(country) {
        var flag_img_name = "";
    
        if (country.toLowerCase() == "us") {
          flag_img_name = "flag_us16x13.gif";
        } else if (country.toLowerCase() == "ca"){
          flag_img_name = "flag_ca16x13.gif";
        }
    
        return flag_img_name;
      }
    };
    
    ejs.render(template, data);
    

    在您的模板中:

    <img src="http://some_url_path/<%=getFlag(data_point[0].country_name) %>" width="16" height="14" alt="country" >
    

    【讨论】:

      【解决方案4】:

      在一个 js 文件中,创建一个函数的实例,例如:如果你的函数名是 test ()Var ren = test (); 将创建对该函数的引用。

      在将数据渲染到 ejs 页面之前,将引用变量 ren 添加到该对象:

      Data.ren = ren();
      
      Res.render(Data)
      

      现在在 ejs 中,当你调用 &lt;% ren() %&gt; 时,它会调用函数。

      【讨论】:

        【解决方案5】:

        您可以只需要一个单独的文件并将 app.locals 设置为此

        app.locals = require('./path/helpers')
        

        在 helpers.js 中:

        getFlag = function(country) {
        var flag_img_name = "";
        if (country.toLowerCase() == "us") {
            flag_img_name = "flag_us16x13.gif";
        }   
        else if (country.toLowerCase() == "ca"){
            flag_img_name = "flag_ca16x13.gif";
        }
        return flag_img_name; 
        }
        anotherFunction=function(x){
        return 'hello '+x
        }
        
           module.exports={getFlag, anotherFunction}
        

        【讨论】:

        • 在我的控制器操作中,ReferenceError: app is not defined。你把你的第一个sn-p放在哪里? (也就是说:app.locals应该分配到哪里?)
        • 回答我自己的评论,在任何定义或导入 const app = express(); 的地方,例如 app.js 本身。
        【解决方案6】:

        设置文件的顺序对函数的定义方式很重要。执行是自上而下的,而不是文档评估。下面的示例来设置您的功能。

        document.html

        <section class="container">
            <%- include('./helpers/common') %>
            <%- include('./home') %>
        </section>
        

        common.ejs

        <%
        MyFunction = function() {
            // Write your code here
        }
        %>
        

        home.ejs

        <% if(MyFunction() ) { %>
            <!-- Write your HTML markup -->
        <% }%>
        

        【讨论】:

          【解决方案7】:

          在js文件helper.js中创建常用函数。

          function common1() {
              //function body
          }
          function common2(key) {
              //function body
          }
          module.exports = {
              common1: common1,
              common2: common2
          }
          

          然后在你的节点函数中需要这个文件

          var helper = require('./helper');
          

          然后通过 ejs 渲染传递这个帮助器

          res.render('index', { helper:helper });
          

          而使用你的函数是ejs文件

          <%= helper.common1() %>
          

          就是这样

          【讨论】:

          • 对我来说不起作用; module.exports 不应该有键值对。 @Rik 下面的评论显示了正确的 module.exports 格式。
          • module.exports 实际上有键值对; module.exports = { oneFn, anotherFn } 的替代语法利用了一个名为 Enhanced Object Literals 的 ES6 特性,特别是属性值简写。键值对只是透明地发生。
          • 这对我有用。我能够轻松地将对我在模型和控制器中使用的函数文件的引用传递给 EJS 上下文,例如:res.status(200).render('view', { Functions: Functions, other:data })
          • 这对我有用,应该是公认的答案。我一直在努力尝试获得公认的答案以进行编译。我在 30 分钟内完成了这个答案并进行了重构,这是一种很好的方法。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-15
          • 2020-09-13
          • 2020-03-21
          • 2013-04-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多