Pregunta

Llamo a un servicio web que devuelve una matriz de objetos en JSON. Quiero tomar esos objetos y llenar un div con HTML. Digamos que cada objeto contiene una url y un nombre.

Si quisiera generar el siguiente HTML para cada objeto:

<div><img src="the url" />the name</div>

¿Hay una mejor práctica para esto? Puedo ver algunas formas de hacerlo:

  1. Concatenar cadenas
  2. Crear elementos
  3. Use un complemento de plantillas
  4. Genere el html en el servidor y, a continuación, sirva a través de JSON.
¿Fue útil?

Solución

Las opciones # 1 y # 2 serán tus opciones directas más inmediatas, sin embargo, para ambas opciones, sentirás el impacto en el rendimiento y el mantenimiento ya sea creando cadenas o creando objetos DOM.

La plantilla no es tan inmadura, y la estás viendo emergente en la mayoría de los principales marcos de Javascript.

Aquí hay un ejemplo en JQuery Template Plugin que le ahorrará el impacto en el rendimiento, y es realmente, muy sencillo:

var t = $.template('<div><img src="${url}" />${name}</div>');

$(selector).append( t , {
     url: jsonObj.url,
     name: jsonObj.name
});

Yo digo que vayas por la buena ruta (y con mejor rendimiento, más fácil de mantener), y utilices plantillas.

Otros consejos

Si absolutamente tiene que concatenar cadenas, en lugar de lo normal:

var s="";
for (var i=0; i < 200; ++i) {s += "testing"; }

usa una matriz temporal:

var s=[];
for (var i=0; i < 200; ++i) { s.push("testing"); }
s = s.join("");

El uso de matrices es mucho más rápido, especialmente en IE. Hice algunas pruebas con cadenas hace un tiempo con IE7, Opera y FF. Opera solo tardó 0.4 segundos en realizar la prueba, ¡pero IE7 no había terminado después de 20 MINUTOS! (No, no estoy bromeando). Con la matriz IE fue muy rápido.

Cualquiera de las dos primeras opciones es común y aceptable.

Daré ejemplos de cada uno en Prototype .

// assuming JSON looks like this:
// { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }

Enfoque n. ° 1:

var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
$('container').insert(html); // inserts at bottom

Enfoque # 2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom

Aquí hay un ejemplo, usando mi Plantillas simples plug-in para jQuery:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);

Quizás un enfoque más moderno es usar un lenguaje de creación de plantillas como Moustache , que tiene implementaciones en muchos idiomas, incluido javascript. Por ejemplo:

var view = {
  url: "/hello",
  name: function () {
    return 'Jo' + 'hn';
  }
};

var output = Mustache.render('<div><img src="{{url}}" />{{name}}</div>', view);

Incluso obtienes un beneficio adicional: puedes reutilizar las mismas plantillas en otros lugares, como el lado del servidor.

Si necesita plantillas más complicadas (si hay declaraciones, bucles, etc.), puede usar Barras de manillar que tienen más características, y es compatible con el bigote.

Puede agregar la plantilla HTML a su página en un div oculto y luego usar cloneNode y las funciones de consulta de su biblioteca favorita para llenarla

/* CSS */
.template {display:none;}

<!--HTML-->
<div class="template">
  <div class="container">
    <h1></h1>
    <img src="" alt="" />
  </div>
</div>

/*Javascript (using Prototype)*/
var copy = $(".template .container")[0].cloneNode(true);
myElement.appendChild(copy);
$(copy).select("h1").each(function(e) {/*do stuff to h1*/})
$(copy).select("img").each(function(e) {/*do stuff to img*/})

Divulgación: soy el mantenedor de BOB.

Hay una biblioteca de JavaScript que hace que este proceso sea mucho más fácil llamado BOB .

Para su ejemplo específico:

<div><img src="the url" />the name</div>

Esto se puede generar con BOB mediante el siguiente código.

new BOB("div").insert("img",{"src":"the url"}).up().content("the name").toString()
//=> "<div><img src="the url" />the name</div>"

O con la sintaxis más corta

new BOB("div").i("img",{"src":"the url"}).up().co("the name").s()
//=> "<div><img src="the url" />the name</div>"

Esta biblioteca es bastante poderosa y se puede usar para crear estructuras muy complejas con inserción de datos (similar a d3), por ejemplo:

data = [1,2,3,4,5,6,7]
new BOB("div").i("ul#count").do(data).i("li.number").co(BOB.d).up().up().a("a",{"href": "www.google.com"}).s()
//=> "<div><ul id="count"><li class="number">1</li><li class="number">2</li><li class="number">3</li><li class="number">4</li><li class="number">5</li><li class="number">6</li><li class="number">7</li></ul></div><a href="www.google.com"></a>"

BOB actualmente no admite la inyección de datos en el DOM. Esto está en el todolist. Por ahora, simplemente puede usar la salida junto con JS normal o jQuery, y colocarla donde desee.

document.getElementById("parent").innerHTML = new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s();
//Or jquery:
$("#parent").append(new BOB("div").insert("img",{"src":"the url"}).up().content("the name").s());

Hice esta biblioteca porque no estaba satisfecho con ninguna de las alternativas como jquery y d3. El código es muy complicado y difícil de leer. En mi opinión, trabajar con BOB es, obviamente, sesgado, mucho más agradable.

BOB está disponible en Bower , por lo que puede obtenerlo ejecutando bower install BOB .

  

¿Hay una mejor práctica para esto? Puedo ver algunas maneras de hacerlo:

     
      
  1. Cadenas de concatenación
  2.   
  3. Crear elementos
  4.   
  5. Usa un complemento de plantillas
  6.   
  7. Genere el html en el servidor, luego sirva a través de JSON.
  8.   

1) Esta es una opción. Cree el html con JavaScript en el lado del cliente y luego introdúzcalo en el DOM como un todo.

Tenga en cuenta que hay un paradigma detrás de este enfoque: el servidor genera solo datos y (en caso de interacción) recibe datos del cliente de forma asíncrona con solicitudes AJAX. El código del lado del cliente funciona como una aplicación web JavaScript independiente.

La aplicación web puede funcionar, renderizar la interfaz, incluso sin que el servidor esté activo (por supuesto, no mostrará ningún dato ni ofrecerá ningún tipo de interacción).

Este paradigma se está adoptando a menudo últimamente, y los marcos completos se basan en este enfoque (ver backbone.js por ejemplo).

2) Por razones de rendimiento, cuando sea posible, es mejor crear el html en una cadena y luego inyectarlo como un todo en la página.

3) Esta es otra opción, además de adoptar un marco de aplicación web. Otros usuarios han publicado varios motores de plantillas disponibles. Tengo la impresión de que tienes las habilidades para evaluarlas y decidir si seguir o no este camino.

4) Otra opción. Pero sírvalo como un texto plano / html; ¿Por qué JSON? No me gusta este enfoque porque mezcla PHP (el lenguaje de su servidor) con Html. Pero lo adopto a menudo como un compromiso razonable entre la opción 1 y 4 .


Mi respuesta: ya estás mirando en la dirección correcta.

Sugiero adoptar un enfoque entre 1 y 4 como hago yo. De lo contrario, adopte un marco web o un motor de plantillas.

Solo mi opinión basada en mi experiencia ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top