I am currently making a small module for NodeJs. For which I need a small help.
I will tell it like this. I have a variable with string. It contains a string html va
This solution uses template strings to do everything you want.
This solution has the advantage that, in contrast to the naive roll-your-own regexp-based template replacement strategy as proposed in another answer, it supports arbitrary calculations, as in
replacer("My name is ${name.toUpperCase()}", {name: "Bob"});
In this version of replacer
, we use new Function
to create a function which takes the object properties as parameters, and returns the template passed in evaluated as a template string. Then we invoke that function with the values of the object properties.
function replacer(template, obj) {
var keys = Object.keys(obj);
var func = Function(...keys, "return `" + template + "`;");
return func(...keys.map(k => obj[k]));
}
We define the template using ${}
for substitutions (instead of $()
), but escaping as \${
to prevent evaluation. (We could also just specify it as a regular string literal, but would then lose multi-line capability).
var html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document \${title}</title> <!-- escape $ -->
</head>
<body>
<h1>Test file, \${text}</h1> <!-- escape $ -->
</body>
</html>`;
Now things work exactly as you want:
replacer(html, { "title" : "my title", "text" : "text is this" });
Simple example:
> replacer("My name is ${name}", {name: "Bob"})
< "My name is Bob"
Here's an example of calculated fields:
> replacer("My name is ${name.toUpperCase()}", {name: "Bob"})
< "My name is BOB"
or even
> replacer("My name is ${last ? lastName : firstName}",
{lastName: "Jones", firstName: "Bob", last: true})
< "My name is Jones"
Since you are using ES6 template string you can use a feature called 'tagged template strings'. Using tagged template strings you are allowed to modify the output of a template string. You create tagged template string by putting a 'tag' in front of the template string, the 'tag' is a reference to a method that will receive the string parts in a list as the first argument and the interpolation values as remaining arguments. The MDN page on template strings already provides an example template string 'tag' that we can use:
function template(strings, ...keys) {
return (function(...values) {
var dict = values[values.length - 1] || {};
var result = [strings[0]];
keys.forEach(function(key, i) {
var value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join('');
});
}
You use the 'tag' by calling:
var tagged = template`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document ${'title'}</title>
</head>
<body>
<h1>Test file, ${'text'}</h1>
</body>
</html>`;
Notice that interpolation of variables uses the syntax ${'key'}
instead of $(key)
. You can now call the produced function to get the desired result:
tagged({ "title" : "my title", "text" : "text is this" });
Run the code example on es6console
var binddingData=function(id,data){
var me=this,
arr=[];
arr=getControlBindding(id);
arr.forEach(function(node){
var content=getBinddingContent(node.getAttribute('DataTemp'),data);
binddingToHtml(node,content);
})
}
var getControlBindding=function(id){
var me=this;
return document.querySelectorAll('[DataTemp]');
}
var getBinddingContent=function(temp,data){
var me=this,
res='',
hasNull=false;
if(temp==null||typeof temp=='undefined'){
return res;
}
res= temp.replace(/\$\{([^\}]+)?\}/g, function($1, $2) {
if(data[$2]==null||typeof data[$2]=='undefined'){
hasNull=true;
}
return data[$2];
});
return hasNull?'':res;
}
var binddingToHtml=function(node,content){
var me=this;
if(node.getAttribute('IsDateTime')){
node.innerText='';//if u want change it to datetime string
return;
}
if(node.getAttribute('AddBr') && content==''){
node.innerText='';
var brTag=document.createElement('br');
node.appendChild(brTag);
return;
}
node.innerText=content;
}
You use the 'tag' by calling:
<div DataTemp="${d1}"></div>
<div DataTemp="${d2}"></div>
<div DataTemp="${d3}"></div>
<div DataTemp="${d3}+ +${d1}"></div>
<div DataTemp="${d3}/${d1}"></div>
<div DataTemp="${d4}\${d1}"></div>
<div DataTemp="(${d5}\${d1})"></div>
<div DataTemp="(${d3}\${d1})"></div>
with data var data={d1:'t1',d2:'t2',d3:'t3'}
You can use a simple template function using regex,
var replacer = function(tpl, data) {
var re = /\$\(([^\)]+)?\)/g, match;
while(match = re.exec(tpl)) {
tpl = tpl.replace(match[0], data[match[1]])
re.lastIndex = 0;
}
return tpl;
}
use like
var result = replacer(html, { "title" : "my title", "text" : "text is this" });
jsfiddle
detail here
EDIT
Actually as torazaburo mentioned in the comment, it can be refactored as
var replacer = function(tpl, data) {
return tpl.replace(/\$\(([^\)]+)?\)/g, function($1, $2) { return data[$2]; });
}
jsfiddle
hope this helps