【问题标题】:Resolving template literals at a later context [duplicate]在以后的上下文中解析模板文字[重复]
【发布时间】:2017-01-07 12:24:19
【问题描述】:

我有如下用例,我在其中填充innerHTML,如下所示。现在的问题是我想在 forloop 的上下文中解析模板文字。有什么线索吗?

var blog_entries_dom = 'blog_entries';
var blog_entries = [
    {
        "title": "Hello World",
        "id": 2,
        "body": "<p>Hello World</p>"
    },
    {
        "title": "World Hello",
        "id": 3,
        "body": "<p>World Hello</p>"
    }
];

var blog_entry_template = `<div class="post-preview">
                        <a href="post.html">
                            <h2 class="post-title">
                                ${item.title}
                            </h2>
                            <h3 class="post-subtitle">
                                ${item.body}
                            </h3>
                        </a>
                        <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p>
                    </div>
                    <hr>`;


var populate_children = function (element_id, objects_list, template) {

    var element = document.getElementById(element_id);

    var html = '';

    for (var i = 0; i < list.length; i++) {
        var item = list[i]
        html += template;
    }

    element.innerHTML = html;
};

populate_children(blog_entries_dom, blog_entries, blog_entry_template);

【问题讨论】:

  • 推荐的方法是什么?我手头有一个模板和对象列表,我需要缝合它们。

标签: javascript template-literals


【解决方案1】:

模板字面量就是:字面量。就像所有文字一样,它们在出现的位置进行评估。它们不是对象,你不能传递它们。

您可以做的是将它们放在一个函数中并传递该函数。让函数接受模板需要的东西,并返回评估结果。

在您的情况下,您只需将 blog_entry_template 更改为箭头函数,然后调用它:

var blog_entries_dom = 'blog_entries';
var blog_entries = [
    {
        "title": "Hello World",
        "id": 2,
        "body": "<p>Hello World</p>"
    },
    {
        "title": "World Hello",
        "id": 3,
        "body": "<p>World Hello</p>"
    }
];

var blog_entry_template = item => `<div class="post-preview">
    <a href="post.html">
        <h2 class="post-title">
            ${item.title}
        </h2>
        <h3 class="post-subtitle">
            ${item.body}
        </h3>
    </a>
    <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p>
</div>
<hr>`;


var populate_children = function (element_id, objects_list, template) {

    var element = document.getElementById(element_id);

    var html = '';

    for (var i = 0; i < list.length; i++) {
        html += template(list[i]);
    }

    element.innerHTML = html;
};

用法:

populate_children("some-id", blog_entries, blog_entry_template);

【讨论】:

  • (Doh!编辑错误,如果您在任何地方看到var formatItem =...,请点击刷新。)
  • 那么如何将模板保留在此方法之外?因为这个方法是通用的,并且会接受模板文字作为参数。
  • @itsneo:这不是你的问题。答案是:模板字面量就是:字面量。它们不是对象,你不能传递它们。您可以做的是将它们放在一个函数中并传递该函数。你让函数接受模板需要的东西,并返回评估它的结果。
  • 这是我对 var populate_children = function (element_id, objects_list, template) {} 方法的预期签名看起来我需要重新发明自己的模板解析器
  • @itsneo:我已经更新了答案以反映更新后的问题,这更加清晰。 (当我这样做时,您接受了答案,这表明您知道它是如何应用的。:-))
【解决方案2】:

我有其他解决方案,使用原型可能是个好主意!

String.prototype.replaceTemp = function(replaceObj) {
   return this.replace(/{\$(\w{1,20})}/g, function(matchStr, agr) {
     if (replaceObj[agr] instanceof Object || replaceObj[agr] instanceof Function) {
       var _tempPool = (window.TEMP_POOL = window.TEMP_POOL || []);
       var _length = _tempPool.length;
       _tempPool[_length] = replaceObj[agr];

       if (replaceObj[agr] instanceof Function)
         return "TEMP_POOL[" + _length + "](this);"
       else
         return "TEMP_POOL[" + _length + "]";

     } else {
       return replaceObj[agr] || "";
     }

   });
 };


    var blog_entries_dom = 'blog_entries';
    var blog_entries = [
        {
            "title": "Hello World",
            "id": 2,
            "body": "<p>Hello World</p>"
        },
        {
            "title": "World Hello",
            "id": 3,
            "body": "<p>World Hello</p>"
        }
    ];

    var blog_entry_template = `<div class="post-preview">
                            <a href="post.html">
                                <h2 class="post-title">
                                    {$title}
                                </h2>
                                <h3 class="post-subtitle">
                                    {$body}
                                </h3>
                            </a>
                            <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p>
                        </div>
                        <hr>`;


    var populate_children = function (element_id, objects_list, template) {

        var element = document.getElementById(element_id);

        var html = '';

        for (var i = 0; i < list.length; i++) {
            html += template.replaceTemp(list[i]);
        }

        element.innerHTML = html;
    };

【讨论】:

  • 不,扩展内置原型并不是一个好主意。而那个全球性的TEMP_POOL 肯定是个坏人。
  • 内置prototype方便使用,全局TEMP_POOL绑定事件,否则必须先创建DOM元素再绑定事件,不过只是简单的替换模板中的变量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-16
  • 2011-11-15
  • 2017-06-19
相关资源
最近更新 更多