6

mi piacerebbe fare quanto segueModi di interpolare variabili di modello all'interno oggetti JavaScript

var obj = { 
    animal: "${animal}" 
}; 

var res = magic(obj, {animal: "cat"}); 

// res => {animal: "cat"} 

magic è una funzione che fa il lavoro sporco. Ovviamente obj potrebbe essere più complesso con più chiavi, array annidati e così via. La variabile di modello potrebbe essere all'interno di un array come questo

var obj = { 
    animals: ["cat", "dog", "${animal}", "cow"] 
}; 

e potrebbe essere ovunque nella matrice in modo semplicemente facendo obj.animals[2] = "bat"; non è fattibile.

Ho trovato il underscore-tpl library con cui posso ottenere quello che voglio, ma vorrei sapere se ci sono altre soluzioni per riferimento futuro e perché ho avuto difficoltà a trovare underscore-tpl in primo luogo.

Il mio uso reale è caso è che ho un file config.json in cui ho diverse dichiarazioni come la seguente

{ 
    "task1": { 
    "command": "command-line-program", 
    "args": [ 
     "--input", "{{input}}", 
     "--flag1", 
     "--output", "{{output}}", 
     "--flag2", 
    ], 
    "options": { 
     "cwd": "path-to-working-dir" 
    } 
    } 
} 

mi parse questo consig.json utilizzando JSON.parse(...) e chiamo require("child_process").spawn con la command, args e i parametri options dichiarati nel file, tuttavia args cambiano molto, le bandiere aggiunte, riordinate e roba, così facendo semplicemente config.task1.args[1] = "<input value>"; si tratta di cambiare il codice che richiama spawn e questo è come soggetto a errori.

Aggiornamento

Sulla base di the accepted answer ho creato un pacchetto semplice (located here), che posso includere nei miei progetti, sentitevi liberi di usarlo.

+1

Perché non solo "animale: res.animal"? Se hai bisogno dell'interpolazione nel mezzo di una stringa più grande, controlla ES2015 [stringhe di template] (http://es6-features.org/#StringInterpolation). * modifica * oh OK vedo cosa stai ricevendo. – Pointy

+0

Cerca motori di template JS. Si noti che la richiesta di risorse esterne, librerie, ecc. È in realtà OT per SO. –

+0

@DaveNewton Beh, ammetto che questo non è il migliore di sempre SO domanda :) Volevo solo mettere qualcosa "là fuori", in modo che io (e altri) potessi trovarlo più facilmente, perché ho avuto difficoltà a trovare una soluzione indolore per questo. –

risposta

2

Si potrebbe JSON.stringify l'oggetto, quindi sostituire il valore di ricerca con il valore effettivo, quindi JSON.parse il risultato:

function magic(o, a) { 
    var j = JSON.stringify(o); 
    for (var k in a) { 
      j = j.split('${'+k+'}').join(a[k]); 
    } 
    return JSON.parse(j); 
} 
+0

Ho provato qualcosa del genere, solo con espressioni regolari che eseguono "cerca e sostituisci" su tutto il mio config.json. Ho avuto problemi con l'escaping delle citazioni mentre analizzavo la stringa su JSON, ma in generale, sì, funziona :) –

+1

Bene, ho seguito il tuo suggerimento, perché questo non poteva essere più semplice. Ho creato un pacchetto basato su questo [qui] (https://github.com/kohanyirobert/tplobj). Ho aggiornato il codice in modo che 'a [k]' venisse correttamente scappato. Finora funziona per me. Grazie per l'idea! –

+0

Questa soluzione sembra destinata a rompersi inaspettatamente, perché non sfugge alle stringhe in 'a'. (Cioè, funzionerà su semplici casi di test, ma poi interromperà la produzione quando otterrai una stringa che contiene una citazione o una barra rovesciata o un somesuch) –

1

suggerisco a voi un molto semplice ma molto veloce e comprensibile motore template: simple-template.js

Consiste di 22 righe di codice, molto semplice! Considerando che, sarete in grado di rendere facilmente la vostra configurazione!