Representación eficiente de muchos cuadros de selección en una página

Estoy trabajando en una aplicación web que hace un uso intensivo de cuadrículas con menús desplegables seleccionados para la entrada de datos. La cuadrícula consta de filas de cuadros de selección. En algunas situaciones, puede haber cientos de cuadros de selección en la página al mismo tiempo.

Por el momento, renderizo la grilla de forma similar al siguiente método:

function render(jsonData) {
    var html = [];
    $.each(jsonData.Rows, function (i, row) {
        html.push('<tr data-id="', row.Id, '"><td>');
        renderSelect(html, globalVar.ArrayX, row.ValueX);
        html.push('</td><td>');
        renderSelect(html, globalVar.ArrayY, row.ValueY);
        html.push('</td><td>');
        ...
        html.push('</tr>');
    });
    $('tbody#container').html(html.join(''));
}

function renderSelect(html, set, selectedValue) {
    html.push('<select>');
    $.each(set, function (i, item) {
        html.push('<option value="', item.Id, '"', item.Id === selectedValue ? ' selected="1"' : '', '>', item.Name, '</option>');
    });
    html.push('</select>');
}

La mayoría de los cuadros de selección tienen las mismas opciones, solo con diferentes elementos seleccionados por fila (por lo que no puedo simplemente almacenar en caché el html del cuadro de selección).

El rendimiento no es terrible, Chrome representa la cuadrícula en 1 segundo y FF e IE en aproximadamente 2. Todavía me pregunto si puede haber una alternativa más eficiente en memoria/rendimiento para crear estos cuadros de selección, tal vez alguna forma de hacer referencia a ellos en su lugar. de volver a crearlos para cada fila?

preguntado el 01 de junio de 12 a las 13:06

no probado, pero en lugar de html.push (... ¿por qué no solo una variable de texto simple de html +=? No unirse al final. -

@vlzvl La concatenación de cadenas es un poco más rápida para los navegadores modernos, pero mucho más lenta para los navegadores más antiguos (IE <8). Lo intentaré de todos modos. -

Aquí hay un violín jsfiddle.net/Jwx6C/3 para jugar en función de su código anterior. -

1 Respuestas

Crea el selecciona una vez y use clonar para colocarlo donde lo necesite. Si la estructura HTML es literalmente la misma, todo lo que tendría que hacer después de eso es seleccionar el valor apropiado para cada selecciona

http://api.jquery.com/clone/

Su otra alternativa es crear una matriz html para el selecciona una vez antes de tu cada declaración, únala en una cadena, y dentro de la cada declaración aplíquelo a su el resto de su html seleccionando su el seleccionado opción después de haber sido agregado. (Espero que tenga sentido.)

De cualquier manera, escriba su fila y el cuadro de selección de antemano, clonándolo (o copiando la cadena) para cada bucle y seleccionando el opción por separado para cada uno, será su opción de mayor rendimiento.

Aquí hay una posible solución usando clon. No aprovecha el rendimiento de la manipulación de cadenas sobre los anexos, pero puede crear una versión alternativa para sus propósitos.

// construct your html ahead of time
var rowHtml = [];
rowHtml.push('<tr"><td>');
rowHtml.push('<select>');
$.each(globalVar.ArrayX, function (i, item) {
    rowHtml.push('<option value="', item.Id, '"', '>', item.Name, '</option>');
});
rowHtml.push('</select>');
rowHtml.push('</td><td>');
$.each(globalVar.ArrayY, function (i, item) {
    rowHtml.push('<option value="', item.Id, '"', '>', item.Name, '</option>');
});
rowHtml.push('</select>');
rowHtml.push('</td><td>');
rowHtml.push('</tr>');
var rowTemplate = $(rowHtml.join(''));

// make a variable for the container once so we can save time performing the DOM lookup
var container = $('tbody#container');

$(jsonData.Rows).each(function (i, row) {
    // since I have to do lookups I've chosen to manipulate attributes using jquery
    // this should move quickly now that we are just cloning
    var clone = rowTemplate.clone();
    clone.attr("data-id", row.Id);
    $("select option[value=" + row.ValueX + "]", clone).attr("selected", "selected");
    container.append(clone);
});

Otra alternativa, si no desea realizar la clonación y las búsquedas de jquery, sería realizar una manipulación de cadenas en la que busque el índice del valor="X" declaración e inserte su seleccionado = seleccionado.

Respondido el 01 de junio de 12 a las 13:06

Intentaré adaptarlo a mi situación. Una cosa: no todas las filas tendrán exactamente los mismos cuadros de selección, por lo que no podré usar una sola plantilla de fila. - Carvellis

Esta técnica va a golpear el DOM repetidamente. Si realiza un pequeño cambio, como colocar los clones en un objeto que no sea DOM, y luego empuja ese objeto terminado en el contenedor, tendrá un mejor reflujo. Solo tenga cuidado cada vez que tenga un ciclo cerrado con las operaciones DOM. Las manipulaciones de cadenas son más rápidas, pero muy propensas a errores humanos y problemas de mantenimiento. Gran respuesta de cualquier manera. - CS

Además, si está creando una cuadrícula bastante grande, use "desenrollar bucles" para mejorar sus bucles. Sugeriría desenrollar cada fila y hacer un bucle en las filas como una implementación de esa técnica para sus propósitos. - CS

Debido a algunos cambios en los requisitos, opté por una solución ligeramente diferente; sin embargo, aceptaré esta respuesta, ya que me ayudó en el camino. - Carvellis

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.