I letterali del modello ES6 possono essere sostituiti in fase di esecuzione (o riutilizzati)?


129

tl; dr: È possibile rendere letterale un modello riutilizzabile?

Ho provato a utilizzare i letterali modello ma immagino di non capirlo e ora mi sto frustrando. Voglio dire, penso di aver capito, ma "non" dovrebbe essere come funziona o come dovrebbe essere. Dovrebbe andare diversamente.

Tutti gli esempi che vedo (anche i modelli contrassegnati) richiedono che le "sostituzioni" siano fatte al momento della dichiarazione e non al tempo di esecuzione, il che mi sembra del tutto inutile per un modello. Forse sono pazzo, ma un "modello" per me è un documento che contiene token che vengono sostituiti quando lo usi, non quando lo crei, altrimenti è solo un documento (cioè una stringa). Un modello viene memorizzato con i token come token e quei token vengono valutati quando tu ... lo valuti.

Tutti citano un orribile esempio simile a:

var a = 'asd';
return `Worthless ${a}!`

È carino, ma se lo so già a, vorrei solo return 'Worthless asd'o return 'Worthless '+a. Qual e il punto? Sul serio. Va bene, il punto è la pigrizia; meno vantaggi, più leggibilità. Grande. Ma non è un modello! Non IMHO. E MHO è tutto ciò che conta! Il problema, IMHO, è che il modello viene valutato quando viene dichiarato, quindi, se lo fai, IMHO:

var tpl = `My ${expletive} template`;
function go() { return tpl; }
go(); // SPACE-TIME ENDS!

Poiché expletivenon è dichiarato, restituisce qualcosa di simile My undefined template. Super. In realtà, almeno in Chrome, non posso nemmeno dichiarare il modello; genera un errore perché expletivenon è definito. Quello di cui ho bisogno è essere in grado di eseguire la sostituzione dopo aver dichiarato il modello:

var tpl = `My ${expletive} template`;
function go() { return tpl; }
var expletive = 'great';
go(); // My great template

Tuttavia non vedo come sia possibile, poiché questi non sono realmente modelli. Anche quando dici che dovrei usare i tag, no, non funzionano:

> explete = function(a,b) { console.log(a); console.log(b); }
< function (a,b) { console.log(a); console.log(b); }
> var tpl = explete`My ${expletive} template`
< VM2323:2 Uncaught ReferenceError: expletive is not defined...

Tutto ciò mi ha portato a credere che i letterali modello siano orribilmente errati e dovrebbero essere chiamati per quello che sono realmente: heredocs . Immagino che la parte "letterale" dovrebbe avermi avvertito (come in, immutabile)?

Mi sto perdendo qualcosa? C'è un (buon) modo per rendere letterale un modello riutilizzabile?


Ti do, modelli letterali riutilizzabili :

> function out(t) { console.log(eval(t)); }
  var template = `\`This is
  my \${expletive} reusable
  template!\``;
  out(template);
  var expletive = 'curious';
  out(template);
  var expletive = 'AMAZING';
  out(template);
< This is
  my undefined reusable
  template!
  This is
  my curious reusable
  template!
  This is
  my AMAZING reusable
  template!

Ed ecco una ingenua funzione di "aiuto" ...

function t(t) { return '`'+t.replace('{','${')+'`'; }
var template = t(`This is
my {expletive} reusable
template!`);

... per renderlo "migliore".

Sono incline a chiamarli guterals modello a causa dell'area da cui producono sentimenti tortuosi.


1
Supporta il barrato (ma non nei commenti come questo). Metti il ​​tuo testo in un <strike>tag.
Pointy

I letterali del modello ES6 sono principalmente per l'interpolazione di stringhe vecchio stile. Se vuoi modelli dinamici usa Handlebars ecc. O la soluzione di modelli con tag di Pointy.
joews

1
Nonostante il nome, le stringhe dei modelli non sono modelli . Vedi anche Posticipare l'esecuzione per ES6 Template Strings
Bergi

8
Potresti per favore rendere il tuo post un po 'meno rumoroso? Inoltre, sembra che tu abbia intenzione di scrivere un tutorial in formato Q&A, se lo hai fatto, rimuovi la parte " Ti do ... " dalla tua domanda e pubblicala come risposta .
Bergi

Ho notato che qui ci sono molte buone risposte. Forse accettane uno.
abalter

Risposte:


86

Per far funzionare questi letterali come altri motori di modelli, è necessario un modulo intermedio.

Il modo migliore per farlo è usare il Functioncostruttore.

const templateString = "Hello ${this.name}!";
const templateVars = {
    name: "world"    
}

const fillTemplate = function(templateString, templateVars){
    return new Function("return `"+templateString +"`;").call(templateVars);
}

console.log(fillTemplate(templateString, templateVars));

Come con altri motori di modelli, puoi ottenere quella stringa da altri posti come un file.

Possono esserci problemi con questo metodo come i tag del modello sono difficili da usare, ma quelli possono essere aggiunti se sei intelligente. Inoltre, non è possibile avere una logica JavaScript in linea a causa dell'interpolazione tardiva. Questo può anche essere risolto con un po 'di riflessione.


8
Bello! Puoi anche usarenew Function(`return \`${template}\`;`)
Ruben Stolk

E questi modelli possono essere composti o "inclusi" tramite argomenti richiamando un metodo o passando il risultato compilato di un altro modello.
Quentin Engles

Quentin cosa significa "nessun tag modello"? Grazie!
mikemaccana

10
attenzione che questa stringa modello è un po '"nascosta" al transpilation (es. webpack) e quindi NON si trasporterà in qualcosa di sufficientemente compatibile (es. IE11) sul lato client ...!
Frank Nocke

9
Vulnerabilità XSS ? Dettagli in QUESTO JSFIDDLE
Kamil Kiełczewski

65

Puoi inserire una stringa modello in una funzione:

function reusable(a, b) {
  return `a is ${a} and b is ${b}`;
}

Puoi fare la stessa cosa con un modello con tag:

function reusable(strings) {
  return function(... vals) {
    return strings.map(function(s, i) {
      return `${s}${vals[i] || ""}`;
    }).join("");
  };
}

var tagged = reusable`a is ${0} and b is ${1}`; // dummy "parameters"
console.log(tagged("hello", "world"));
// prints "a is hello b is world"
console.log(tagged("mars", "jupiter"));
// prints "a is mars b is jupiter"

L'idea è di lasciare che il parser del modello divida le stringhe costanti dalla variabile "slot", e quindi restituisca una funzione che rattoppa tutto di nuovo in base a un nuovo insieme di valori ogni volta.


3
@FelixKling che potrebbe essere; Controllerò e risolverò se è così. modifica sì, sembra che ho tralasciato una parte significativa dell'esempio, essendo la funzione "riutilizzabile" :)
Puntato

@FelixKling Non sono sicuro di cosa fare perché non riesco affatto a ricordare cosa stavo pensando in quel momento!
Pointy

1
Sì, non ha molto senso essere né tbh;) Puoi sempre rimuoverlo ... ma reusablepotrebbe essere implementato in modo che restituisca una funzione, e dovresti usare ${0}e ${1}all'interno del letterale invece di ${a}e ${b}. Quindi puoi usare quei valori per fare riferimento agli argomenti della funzione, in modo simile a quello che fa Bergi nel suo ultimo esempio: stackoverflow.com/a/22619256/218196 (o immagino sia fondamentalmente lo stesso).
Felix Kling

1
@FelixKling OK, penso di aver escogitato qualcosa che è almeno vagamente sulla falsariga dell'OP.
Pointy

3
I modelli con tag possono essere davvero potenti se il risultato non è effettivamente una stringa. Ad esempio, in uno dei miei progetti, lo uso per eseguire l'interpolazione dei nodi AST. Ad esempio, si può fare expression`a + ${node}`per costruire un nodo BinaryExpression con un nodo AST esistente node. Internamente inseriamo un segnaposto per generare codice valido, lo analizziamo come un AST e sostituiamo il segnaposto con il valore passato.
Felix Kling

45

Probabilmente il modo più pulito per farlo è con le funzioni freccia (perché a questo punto stiamo già usando ES6)

var reusable = () => `This ${object} was created by ${creator}`;

var object = "template string", creator = "a function";
console.log (reusable()); // "This template string was created by a function"

object = "example", creator = "me";
console.log (reusable()); // "This example was created by me"

... E per i letterali modello con tag:

reusable = () => myTag`The ${noun} go ${verb} and `;

var noun = "wheels on the bus", verb = "round";
var myTag = function (strings, noun, verb) {
    return strings[0] + noun + strings[1] + verb + strings[2] + verb;
};
console.log (reusable()); // "The wheels on the bus go round and round"

noun = "racecars", verb = "fast";
myTag = function (strings, noun, verb) {
    return strings[0] + noun + strings[1] + verb;
};
console.log (reusable()); // "The racecars go fast"

Questo evita anche l'uso di eval()o Function()che può causare problemi con i compilatori e causare molti rallentamenti.


Penso che questo sia uno dei migliori perché puoi inserire alcuni codici all'interno della funzione myTagper fare alcune cose. Ad esempio, utilizzare i parametri di input come chiave per memorizzare nella cache l'output.
WOW

Penso che questa sia la risposta migliore. È inoltre possibile aggiungere i parametri alla funzione di freccia che a mio avviso lo rende ancora più pulito: var reusable = (value: string) => `Value is ${value}`.
haggisandchips

13

Risposta 2019 :

Nota : la libreria originariamente prevedeva che gli utenti disinfettassero le stringhe per evitare XSS. La versione 2 della libreria non richiede più la disinfezione delle stringhe utente (cosa che gli sviluppatori web dovrebbero fare comunque) poiché evita evalcompletamente.

Il es6-dynamic-templatemodulo su npm fa questo.

const fillTemplate = require('es6-dynamic-template');

A differenza delle risposte attuali:

  • Utilizza stringhe modello ES6, non un formato simile. La versione di aggiornamento 2 utilizza un formato simile, piuttosto che stringhe di modello ES6, per impedire agli utenti di utilizzare stringhe di input non disinfettate.
  • Non è necessario thisnella stringa del modello
  • È possibile specificare la stringa del modello e le variabili in una singola funzione
  • È un modulo mantenuto e aggiornabile, piuttosto che copypasta da StackOverflow

L'utilizzo è semplice. Usa virgolette singole poiché la stringa del modello verrà risolta in seguito!

const greeting = fillTemplate('Hi ${firstName}', {firstName: 'Joe'});

Se lo usi con React Native, si romperà specialmente su Android. Il runtime del nodo Android non supporta i modelli dinamici, solo quelli precompilati
Oliver Dixon

1
Questa è una soluzione che utilizzo nei miei progetti personali e funziona perfettamente. In realtà penso che sia una cattiva idea usare troppe librerie specialmente per piccole utilità come questa.
Oliver Dixon

1
Vulnerabilità XSS ? Dettagli in QUESTO FIDDLE
Kamil Kiełczewski

1
@kamil Solo XSS se a) offri agli utenti la possibilità di creare b) non disinfetti le stringhe di input. Aggiungerò un avvertimento che le persone dovrebbero disinfettare l'input dell'utente.
mikemaccana

1
Questo non utilizza in remoto i letterali del modello es6. Prova 10 * 20 = ${10 * 20}così potrebbe essere un formato simile ma non è nemmeno in remoto letterali modello
es6

12

Sì, puoi farlo analizzando la tua stringa con il modello come JS da Function(o eval), ma questo non è consigliato e consente l' attacco XSS

Invece è possibile inserire in modo sicuro iobj campi oggetto nel modello strin modo dinamico come segue

let inject = (str, obj) => str.replace(/\${(.*?)}/g, (x,g)=> obj[g]);


Questo è il metodo che uso e ha funzionato bene. Buon esempio! Il? dopo l '* nella guida RegEx però? Non sono un esperto di RegEx, ma immagino che dal momento che * significa zero o più (e tu vuoi il "più" in questo caso), non c'è bisogno della restrizione avida?
Gen1-1,

@ Gen1-1 .*?significa non avido - se rimuovi lo "?"snippet darà un risultato sbagliato
Kamil Kiełczewski

Hai ragione, errore mio. Non uso $ nei miei modelli e uso RegEx: / {(\ w *)} / g perché non ho mai spazi nel tag, ma. *? funziona anche. Uso:function taggedTemplate(template, data, matcher) { if (!template || !data) { return template; } matcher = matcher || /{(\w*)}/g; // {one or more alphanumeric characters with no spaces} return template.replace(matcher, function (match, key) { var value; try { value = data[key] } catch (e) { // } return value || ""; }); }
Gen1-1

@ Gen1-1 sono possibili anche dati nidificati? come data = { a: 1, b: { c:2, d:3 } }-> b.c?
muescha

1
@muescha Cambieresti la riga: value = data [chiave], per usare la ricorsione e cercare l'intero oggetto dati e gli oggetti annidati finché non trovi la proprietà. Esempi: codereview.stackexchange.com/questions/73714/… e mikedoesweb.com/2016/es6-depth-first-object-tree-search
Gen1-1

9

Semplificando la risposta fornita da @metamorphasi;

const fillTemplate = function(templateString, templateVars){
  var func = new Function(...Object.keys(templateVars),  "return `"+templateString +"`;")
  return func(...Object.values(templateVars));
}

// Sample
var hosting = "overview/id/d:${Id}";
var domain = {Id:1234, User:22};
var result = fillTemplate(hosting, domain);

console.log(result);


Questo codice è più autoesplicativo della risposta principale. Ho ottenuto il mio voto
positivo

Ciò dovrebbe consentire di utilizzare variabili o file esterni (in NodeJS) come modelli o di crearli dinamicamente in fase di esecuzione. Senza l'uso di eval.
b01

Vulnerabilità XSS ? Giocherellare con codice dannoso (variabile var hosting) QUI .
Kamil Kiełczewski

7

Se non si desidera utilizzare i parametri ordinati o di contesto / spazi dei nomi per fare riferimento alle variabili nel modello, per esempio ${0}, ${this.something}oppure ${data.something}, si può avere una funzione di modello che si prende cura del scoping per voi.

Esempio di come potresti chiamare un modello del genere:

const tempGreet = Template(() => `
  <span>Hello, ${name}!</span>
`);
tempGreet({name: 'Brian'}); // returns "<span>Hello, Brian!</span>"

La funzione Template:

function Template(cb) {
  return function(data) {
    const dataKeys = [];
    const dataVals = [];
    for (let key in data) {
      dataKeys.push(key);
      dataVals.push(data[key]);
    }
    let func = new Function(...dataKeys, 'return (' + cb + ')();');
    return func(...dataVals);
  }
}

La stranezza in questo caso è che devi solo passare una funzione (nell'esempio ho usato una funzione freccia) che restituisce il letterale del modello ES6. Penso che sia un piccolo compromesso ottenere il tipo di interpolazione riutilizzabile che stiamo cercando.

Eccolo su GitHub: https://github.com/Adelphos/ES6-Reuseable-Template


3
Questo è buono, ma la minificazione (vals, func, ecc.) Non è necessaria, 'cb' non è un callback (questo è interamente codice di sincronizzazione), e puoi semplicemente usare Object.values()eObject.keys()
mikemaccana

3

La risposta breve è semplicemente usare _.template in lodash

// Use the ES template literal delimiter as an "interpolate" delimiter.
// Disable support by replacing the "interpolate" delimiter.
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!'

3

Mi sto perdendo qualcosa? C'è un [buon] modo per rendere letterale un modello riutilizzabile?

Forse mi manca qualcosa, perché la mia soluzione a questo problema mi sembra così ovvia che sono molto sorpreso che nessuno l'abbia già scritto in una domanda così vecchia.

Ho quasi una battuta per questo:

function defer([first, ...rest]) {
  return (...values) => rest.reduce((acc, str, i) => acc + values[i] + str, first);
}

È tutto. Quando voglio riutilizzare un modello e differire la risoluzione delle sostituzioni, mi limito a:

> t = defer`My template is: ${null} and ${null}`;
> t('simple', 'reusable');          // 'My template is: simple and reusable'
> t('obvious', 'late to the party'; // 'My template is: obvious and late to the party'
> t(null);                          // 'My template is: null and undefined'
>
> defer`Choose: ${'ignore'} / ${undefined}`(true, false); // 'Choose: true / false'

L'applicazione di questo tag restituisce un 'function'(invece di a 'string') che ignora tutti i parametri passati al letterale. Quindi può essere richiamato con nuovi parametri in seguito. Se un parametro non ha una sostituzione corrispondente, diventa 'undefined'.


Risposta estesa

Questo semplice codice è funzionale, ma se hai bisogno di un comportamento più elaborato, la stessa logica può essere applicata e ci sono infinite possibilità. Potresti:

  1. Utilizza i parametri originali:

È possibile memorizzare i valori originali passati al letterale nella costruzione e utilizzarli in modi creativi quando si applica il modello. Potrebbero diventare flag, validatori di tipi, funzioni ecc. Questo è un esempio che li utilizza come valori predefiniti:

    function deferWithDefaults([first, ...rest], ...defaults) {
      return (...values) => rest.reduce((acc, curr, i) => {
        return acc + (i < values.length ? values[i] : defaults[i]) + curr;
      }, first);
    }

Poi:

    > t = deferWithDefaults`My template is: ${'extendable'} and ${'versatile'}`;
    > t('awesome');                 // 'My template is: awesome and versatile' 
  1. Scrivi una fabbrica di modelli:

Fallo avvolgendo questa logica in una funzione che prevede, come argomento, una funzione custom che può essere applicata nella riduzione (quando si uniscono i pezzi del template letterale) e restituisce un nuovo template con comportamento custom.

    const createTemplate = fn => function (strings, ...defaults) {
      const [first, ...rest] = strings;
      return (...values) => rest.reduce((acc, curr, i) => {
        return acc + fn(values[i], defaults[i]) + curr;
      }, first);
    };

Quindi potresti, ad esempio, scrivere modelli che escono automaticamente o disinfettano i parametri durante la scrittura di html, css, sql, bash incorporati ...

    function sqlSanitize(token, tag) {
      // this is a gross simplification, don't use in production.
      const quoteName = name => (!/^[a-z_][a-z0-9_$]*$/.test(name) ? `"${name.replace(/"/g, '""')}"` : name);
      const quoteValue = value => (typeof value == 'string' ? `'${value.replace(/'/g, "''")}'` : value);
      switch (tag) {
        case 'table':
          return quoteName(token);
        case 'columns':
          return token.map(quoteName);
        case 'row':
          return token.map(quoteValue);
        default:
          return token;
      }
    }

    const sql = createTemplate(sqlSanitize);

Con questo modello sql ingenuo (ripeto, ingenuo! ) Potremmo costruire query come questa:

    > q  = sql`INSERT INTO ${'table'} (${'columns'})
    ... VALUES (${'row'});`
    > q('user', ['id', 'user name', 'is"Staff"?'], [1, "O'neil", true])
    // `INSERT INTO user (id,"user name","is""Staff""?")
    // VALUES (1,'O''neil',true);`
  1. Accetta parametri con nome per la sostituzione: un esercizio non così difficile, basato su ciò che è stato già dato. C'è un'implementazione in quest'altra risposta .

  2. Fai in modo che l'oggetto di ritorno si comporti come un 'string': Beh, questo è controverso, ma potrebbe portare a risultati interessanti. Mostrato in quest'altra risposta .

  3. Risolvi i parametri all'interno dello spazio dei nomi globale nel sito della chiamata:

Ti do, modelli letterali riutilizzabili:

Bene, questo è ciò che OP ha mostrato il suo addendum, utilizzando il comando evil, voglio dire, eval. Questo può essere fatto senza eval, semplicemente cercando il nome della variabile passato nell'oggetto globale (o finestra). Non mostrerò come farlo perché non mi piace. Le chiusure sono la scelta giusta.


2

Questo è il mio miglior tentativo:

var s = (item, price) => {return `item: ${item}, price: $${price}`}
s('pants', 10) // 'item: pants, price: $10'
s('shirts', 15) // 'item: shirts, price: $15'

Per generalizzare:

var s = (<variable names you want>) => {return `<template with those variables>`}

Se non stai eseguendo E6, potresti anche fare:

var s = function(<variable names you want>){return `<template with those variables>`}

Questo sembra essere un po 'più conciso rispetto alle risposte precedenti.

https://repl.it/@abalter/reusable-JS-template-literal


2

In generale sono contrario all'uso del male eval(), ma in questo caso ha senso:

var template = "`${a}.${b}`";
var a = 1, b = 2;
var populated = eval(template);

console.log(populated);         // shows 1.2

Quindi, se modifichi i valori e chiami di nuovo eval (), ottieni il nuovo risultato:

a = 3; b = 4;
populated = eval(template);

console.log(populated);         // shows 3.4

Se lo vuoi in una funzione, allora può essere scritto in questo modo:

function populate(a, b){
  return `${a}.${b}`;
}

Se si sta scrivendo una funzione che include il modello, è sicuramente non si dovrebbe usare eval.
Bergi

@Bergi Why? In che modo è diverso dalla tua implementazione?
isapir

2
Le ragioni che "mi sembra di sapere" si applicano a qualsiasi codice creato dinamicamente. Scrivere la funzione in modo che costruisca il risultato senza chiamare eval()esplicitamente è esattamente lo stesso di eval(), quindi non vi è alcun vantaggio in quanto rende il codice più difficile da leggere.
isapir

1
Esattamente. E poiché la tua populatefunzione non crea dinamicamente il codice, non dovrebbe essere utilizzata evalcon tutti i suoi svantaggi.
Bergi

6
la tua funzione potrebbe essere solo function populate(a,b) { return `${a}.${b}`; }l'eval non aggiunge nulla
Vitim.us

1

AGGIORNATO: La seguente risposta è limitata ai nomi di singole variabili, quindi modelli come: 'Result ${a+b}'non sono validi per questo caso. Tuttavia puoi sempre giocare con i valori del modello:

format("This is a test: ${a_b}", {a_b: a+b});

RISPOSTA ORIGINALE:

Basato nelle risposte precedenti ma creando una funzione di utilità più "amichevole":

var format = (template, params) => {
    let tpl = template.replace(/\${(?!this\.)/g, "${this.");
    let tpl_func = new Function(`return \`${tpl}\``);

    return tpl_func.call(params);
}

Puoi invocarlo proprio come:

format("This is a test: ${hola}, second param: ${hello}", {hola: 'Hola', hello: 'Hi'});

E la stringa risultante dovrebbe essere:

'This is a test: Hola, second param: Hi'

Che ne dici di un modello come questo? `Result: ${a+b}`
Atiris

1
Ciao @Atiris, hai ragione, è un limite, ho aggiornato la mia risposta.
Roberto

1

Se stai cercando qualcosa di piuttosto semplice (solo campi variabili fissi, nessun calcolo, condizionali ...) ma che funziona anche lato client su browser senza il supporto di stringhe di modello come IE 8,9,10,11 ...

eccoci qui:

fillTemplate = function (templateString, templateVars) {
    var parsed = templateString;
    Object.keys(templateVars).forEach(
        (key) => {
            const value = templateVars[key]
            parsed = parsed.replace('${'+key+'}',value)
        }
    )
    return parsed
}

Questo farà una ricerca per ogni variabile. C'è un altro modo che sostituisce tutte le occorrenze contemporaneamente che ho implementato in questo modulo: safe-es6-template
Aalex Gabi

1

Ero seccato per la ridondanza supplementare necessario di digitare this.ogni volta, così ho aggiunto anche regex per espandere le variabili come .aad this.a.

Soluzione:

const interp = template => _thisObj =>
function() {
    return template.replace(/\${([^}]*)}/g, (_, k) =>
        eval(
            k.replace(/([.a-zA-Z0-9$_]*)([a-zA-Z0-9$_]+)/, (r, ...args) =>
                args[0].charAt(0) == '.' ? 'this' + args[0] + args[1] : r
            )
        )
    );
}.call(_thisObj);

Utilizzare come tale:

console.log(interp('Hello ${.a}${.b}')({ a: 'World', b: '!' }));
// outputs: Hello World!

1

Pubblico solo un pacchetto npm che può semplicemente fare questo lavoro. Profondamente ispirato da questa risposta .

const Template = require('dynamic-template-string');

var tpl = new Template('hello ${name}');

tpl.fill({name: 'world'}); // ==> 'hello world';
tpl.fill({name: 'china'}); // ==> 'hello china';

Il suo attrezzo è mortalmente semplice. Vorrei che ti piacesse.


module.exports = class Template {
  constructor(str) {
    this._func = new Function(`with(this) { return \`${str}\`; }`);
  }

  fill(data) {
    return this._func.call(data);
  }
}

1

puoi usare la funzione freccia in linea come questa, definizione:

const template = (substitute: string) => `[^.?!]*(?<=[.?\s!])${substitute}(?=[\s.?!])[^.?!]*[.?!]`;

utilizzo:

console.log(template('my replaced string'));

1

Stringa modello runtime

var templateString = (template, values) => {
    let output = template;
    Object.keys(values)
        .forEach(key => {
        output = output.replace(new RegExp('\\$' + `{${key}}`, 'g'), values[key]);
    });
    return output;
};

Test

console.debug(templateString('hello ${word} world', {word: 'wonderful'}));

0

const fillTemplate = (template, values) => {
  template = template.replace(/(?<=\${)\w+(?=})/g, v=>"this."+v);
  return Function.apply(this, ["", "return `"+template+"`;"]).call(values);
};

console.log(fillTemplate("The man ${man} is brother of ${brother}", {man: "John", brother:"Peter"}));
//The man John is brother of Peter

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.