2011-09-08 13 views
17

Estoy intentando configurar un script para concatenar algunas variables dentro de una cadena si existen, para colocar las etiquetas de metadatos apropiadas en un documento HTML procesado.Cadenas de concatenación con declaraciones `if` en JavaScript

Mi código es la concatenación:

data = "<html>\n<head>\n" + "</head>\n<body>\n\n" + paras.join("\n\n") + "\n\n</body>\n</html>"; 

estoy tratando de añadir if declaraciones como la siguiente en él (entre el primer y segundo puntos):

if (typeof metadata_title !== "undefined") { 
     "<title>" + metadata_title + "</title>\n" 
    } 
    if (typeof metadata_author !== "undefined") { 
     "<meta name=\"author\" content=\"" + metadata_author + "\"></meta>\n" 
    } 
    if (typeof metadata_date !== "undefined") { 
     "<meta name=\"date\" content=\"" + metadata_date + "\"></meta>\n" 
    } 

pero no puedo agregue cualquiera de estas instrucciones directamente en el código de concatenación (arroja un error: Unexpected token ().

¿Qué mejor manera de agregar sentencias como estas a mi cadena de concatenación?

Respuesta

30

que haría uso de un ternary operator:

data = "<html>\n" 
    + "<head>\n" 
    + (typeof metadata_title !== "undefined" ? "<title>" + metadata_title + "</title>\n"        : "") 
    + (typeof metadata_author !== "undefined" ? "<meta name=\"author\" content=\"" + metadata_author + "\"></meta>\n" : "") 
    + (typeof metadata_date !== "undefined" ? "<meta name=\"date\" content=\"" + metadata_date + "\"></meta>\n"  : "") 
    + "</head>\n" 
    + "<body>\n" 
    + "\n" 
    + paras.join("\n\n") 
    + "\n" 
    + "\n" 
    + "</body>\n" 
    + "</html>" 
; 
+1

+3

En casos excepcionales ('var undefined = 'test';') el resultado es incorrecto. Usar 'typeof' es ahorrar. – scessor

+0

Si una de las variables no está definida obtendrá un 'ReferenceError'. Creo que esto es lo que el OP tenía en mente. El suyo está perfectamente bien si se definen los tres metadatas, por supuesto. –

5
data = "<html>\n<head>\n" 
    + (
     typeof metadata_title !== "undefined" ? 
     "<title>" + metadata_title + "</title>\n" : 
     "" 
    ) 
    + (
     typeof metadata_author !== "undefined" ? 
     "<meta name=\"author\" content=\"" + metadata_author + "\"></meta>\n" : 
     "" 
    ) 
    + (
     typeof metadata_date !== "undefined" ? 
     "<meta name=\"date\" content=\"" + metadata_date + "\"></meta>\n" : 
     "" 
    ) 
    + "</head>\n<body>\n\n" 
    + paras.join("\n\n") 
    + "\n\n</body>\n</html>"; 
1

Construir el documento completo en una matriz, a continuación, se unen con un "\n" al final. (La razón de esto es, por supuesto, para no tener un montón de nuevas líneas dispersos por todo alrededor y si usted está en Internet Explorer 7 o menos, Array#join es considerablemente más rápido que la concatenación de cadenas repetidas!).

Código aquí: http://jsfiddle.net/ZCbCZ/

ACTUALIZACIÓN Olvidé incluir los "paras" en el primer violín. El código con los párrafos está aquí: http://jsfiddle.net/U8325/1/

Para aquellos que no deseen hacer clic a través y probarlo, aquí es el guión:

// Not going to define metadata_author just to be saved by typeof :-) 
var metadata_title = "Hello"; 
var metadata_date = "2011-09-07"; 

// Okay 3 paras for fun 
var paras = ["<p>paragraph1</p>", "<p>paragraph2</p>", "<p>paragraph3</p>"]; 

data = ["<html>", "<head>"] 

if (typeof metadata_title !== "undefined") { 
    data.push("<title>" + metadata_title + "</title>"); 
} 
if (typeof metadata_author !== "undefined") { 
    data.push("<meta name=\"author\" content=\"" + metadata_author + "\"></meta>"); 
} 
if (typeof metadata_date !== "undefined") { 
    data.push("<meta name=\"date\" content=\"" + metadata_date + "\"></meta>"); 
} 

data.push("</head>"); 
data.push("<body>"); 
paras.forEach(function (p) {data.push(p);}); // Requires ES5; use a for-loop if you don't have it 
data.push("</body>"); 
data.push("<html>"); 
data = data.join("\n"); 
alert(data); 
5

que podría hacer algo un poco diferente (un poco más parecido a de plantillas), principalmente porque odio HTML concatenada hacer con Javascript:

var metadata_title = "Hello"; 
var metadata_author = "Me"; 
var metadata_date = "2011-09-07"; 

var template = "<html>\ 
      <head>\ 
       <title>#title#</title>\ 
       <meta name=\"author\" content=\"#author#\"></meta>\ 
       <meta name=\"date\" content=\"#date#\"></meta>\ 
      </head>\ 
      <body>\ 
      </body>\ 
      </html>"; 

var data = template.replace("#title#", metadata_title != undefined ? metadata_title : "") 
        .replace("#author#", metadata_author != undefined ? metadata_author : "") 
        .replace("#date#", metadata_date != undefined ? metadata_date : ""); 

Claro, hay un muy pequeña cantidad de sobrecarga adicional, pero para mí, es manera más legible.

+0

¿Cómo obtendrías los "paras" aquí? (No es que sea difícil, solo me gustaría ver lo que se te ocurriría en ausencia de un verdadero motor de tempating. Saludos.) –

+0

A menos que me falte algo (es tarde y necesito dormir), lo más probable es que simplemente agregue '# paras #' entre las etiquetas 'body' y lo reemplace del mismo modo que otros elementos se reemplazan .. 'join' solo devuelve una cadena, así que supongo que funcionará. –

+0

Ah, perfecto, +1 –

1

Me gustó la legibilidad de Demian Brecht respuesta, pero yo sólo iba a cambiar la cadena para una expresión regular lugar, debido a que el replace() función sólo reemplaza el primer partido (ver más aquí: JavaScript .replace only replaces first Match)

var metadata_title = "Hello"; 
var metadata_author = "Me"; 
var metadata_date = "2011-09-07"; 

var template = "<html>\ 
      <head>\ 
       <title>#title#</title>\ 
       <meta name=\"author\" content=\"#author#\"></meta>\ 
       <meta name=\"date\" content=\"#date#\"></meta>\ 
      </head>\ 
      <body>\ 
      </body>\ 
      </html>"; 

var data = template.replace(/#title#/g, metadata_title != undefined ? metadata_title : "") 
        .replace(/#author#/g, metadata_author != undefined ? metadata_author : "") 
        .replace(/#date#/g, metadata_date != undefined ? metadata_date : ""); 
Cuestiones relacionadas