JavaScript简单模板带有递归的模板不会将递归儿童附加到节点
我目前正在使用JavaScript中的一个非常简单的模板引擎,该引擎需要递归模板的功能。这个想法是让一个< template>/template>
具有一个特殊字段,再次被模板递归替换。
class Template {
constructor(template, container) {
this.template = template;
this.container = container;
this.node = [];
}
render_single(template, node, data) {
// replace all occurences of {{.*?}} with template data
node.innerHTML = template.content.children[0].innerHTML.replace(/{{(.*?)}}/g, (match) => {
var key = match.split(/{{|}}/).filter(Boolean)[0];
// replace with data from data array or clear the field
if (key in data) {
return data[key];
} else {
console.log("WARNING: " + key + " not found in data array");
}
return "";
});
node.innerHTML = node.innerHTML.replace(/!!(.*?)!!/g, (match) => {
var key = match.split(/!!|!!/).filter(Boolean)[0];
switch (key.substr(0, 1)) {
case 'R': // recursive
var rkey = key.substr(2);
if (rkey in data) {
var rnode = node.querySelector('.' + rkey);
var rtemplate = new Template(this.template, rnode);
rtemplate.render(data[rkey]);
}
break;
}
return "";
});
this.container.append(node);
}
render(data) {
for (var j = 0; j < data.length; j++) {
for (var i = 0; i < this.template.length; i++) {
var node = this.template[i].content.children[0].cloneNode(true);
this.render_single(this.template[i], node, data[j]);
}
}
}
}
window.onload = function() {
var data = [{
name: "Test1",
childs: [{
name: "Test Childs 1"
},
{
name: "Test Childs 2"
},
]
},
{
name: "Test2"
},
{
name: "Test3"
},
{
name: "Test4"
},
];
var container = document.querySelector('#test');
var template = container.getElementsByTagName('template');
test = new Template(template, container);
test.render(data);
}
<div id="test">
<template>
<div class="test">
<p>Template {{name}}</p>
<div class="childs">!!R childs!!</div>
</div>
</template>
</div>
”节点会附加。递归的人没有。出于测试目的,我将它们附加到例如。 document.body.body
而不是rnode
(示例中的JS代码的第28行)它们会附加。
在将父节点附加到它之前需要更新父节点吗?
I'm currently working on a very simple Template engine in JavaScript which needs the feature of recursive Templating. The idea is to have one <template></template>
which has a special Field that gets recursively replaced by the Template again.
class Template {
constructor(template, container) {
this.template = template;
this.container = container;
this.node = [];
}
render_single(template, node, data) {
// replace all occurences of {{.*?}} with template data
node.innerHTML = template.content.children[0].innerHTML.replace(/{{(.*?)}}/g, (match) => {
var key = match.split(/{{|}}/).filter(Boolean)[0];
// replace with data from data array or clear the field
if (key in data) {
return data[key];
} else {
console.log("WARNING: " + key + " not found in data array");
}
return "";
});
node.innerHTML = node.innerHTML.replace(/!!(.*?)!!/g, (match) => {
var key = match.split(/!!|!!/).filter(Boolean)[0];
switch (key.substr(0, 1)) {
case 'R': // recursive
var rkey = key.substr(2);
if (rkey in data) {
var rnode = node.querySelector('.' + rkey);
var rtemplate = new Template(this.template, rnode);
rtemplate.render(data[rkey]);
}
break;
}
return "";
});
this.container.append(node);
}
render(data) {
for (var j = 0; j < data.length; j++) {
for (var i = 0; i < this.template.length; i++) {
var node = this.template[i].content.children[0].cloneNode(true);
this.render_single(this.template[i], node, data[j]);
}
}
}
}
window.onload = function() {
var data = [{
name: "Test1",
childs: [{
name: "Test Childs 1"
},
{
name: "Test Childs 2"
},
]
},
{
name: "Test2"
},
{
name: "Test3"
},
{
name: "Test4"
},
];
var container = document.querySelector('#test');
var template = container.getElementsByTagName('template');
test = new Template(template, container);
test.render(data);
}
<div id="test">
<template>
<div class="test">
<p>Template {{name}}</p>
<div class="childs">!!R childs!!</div>
</div>
</template>
</div>
https://jsfiddle.net/sessl3r/edpL1jgy/
My problem is that only the top-level Nodes get appended. The recursive ones do not. When for testing purposes I append them to eg. document.body
instead of rnode
(line 28 of JS code in the example) they get appended.
Is there something needed to update the parent Node before appending it to it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我建议您使用现有的模板引擎, mustache 或车把,但是如果这是为了学习目的,则可以。我看到您的代码至少一个问题。当您用文档替换它时,您的代码正常工作。由于您将孩子附加在一个不是您操纵InnerHTTML属性的容器上。您的代码问题在于以下(添加了我的评论):
如果您移动
this.container.append(node);
line,则可以清楚地查看该过程。 render_single funciton并通过这些步骤进行调试。输出将首先包含模板,然后更换名称,然后添加孩子,然后删除所有孩子。与您看到的最终结果相同。First I would suggest you use an existing template engine, mustache or handlebars, but it is ok if this is for learning purposes. I see at least one issue with your code. Your code works when you replace it with document.body since you are appending the children on a container that is not the one that you are manipulating the innerHTTML attribute for. The problem with your code lies in the following (added my comments):
You can clearly see the process if you move the
this.container.append(node);
line at the top of therender_single
funciton and debug through the steps. The output will first contain the template, then replace the name, then add the children and later remove everything of the children. The same as the end result you see.