Evite el formato duplicado entre la vista Razor del lado del servidor y la plantilla jQuery del lado del cliente

Tengo una página de resultados de búsqueda donde genero una lista de elementos formateados de una manera particular usando una vista MVC Razor.

@for (int i = 0; i < group.Count(); i++) {
  <div class="result">
    <div class="ordinal">@((i+1).ToString()).</div>
    <div class="detail"><p>@group.ElementAt(i).Name</p></div>
  </div>
}

El cliente puede filtrar aún más esos resultados utilizando jQuery AJAX para recuperar un nuevo conjunto de datos como plantillas JSON y jQuery para representar el conjunto de resultados en lugar del original. Esta es la plantilla jQuery:

<script id="resultTemplate" type="text/x-jquery-tmpl">
  {{each(i, result) results}}
    <div class="result">
      <div class="ordinal">${i+1}.</div>
      <div class="detail"><p>${name}</p></div>
    </div>
  {{/each}}
</script>

que está vinculado después de la llamada AJAX:

var result = $("#resultTemplate").tmpl({ results: data });
$("#resultsColumn").empty().append(result);

Tenga en cuenta cómo tuve que duplicar el formato HTML para un resultado de búsqueda tanto en el código Razor del lado del servidor como en el código jQuery del lado del cliente. Me gustaría tener solo una versión de la plantilla enlazada a datos para reducir la posibilidad de discrepancias cuando tenga que hacer cambios.

La lectura Introducción de Stephen Walter a las plantillas jQuery él está insinuando una integración "mejor juntos" cuando usa plantillas jQuery con ASP.NET MVC, así que me preguntaba si hay una instalación que aborde el escenario anterior.

Gracias.

preguntado el 27 de agosto de 11 a las 20:08

2 Respuestas

Supongo que podrías usar el @helper sintaxis para evitar algunas de las marcas duplicadas.

@helper Result(string ordinal, string name) {
    <div class="result">
        <div class="ordinal">@ordinal.</div>
        <div class="detail"><p>@name</p></div>
    </div>
}

Luego use el ayudante para la vista Razor

@for (int i = 0; i < group.Count(); i++) {
    @Result((i+1).ToString(), group.ElementAt(i).Name)
}

y la plantilla jQuery

<script id="resultTemplate" type="text/x-jquery-tmpl">
    {{each(i, result) results}}
        @Result("${i+1}", "${name}")
    {{/each}}
</script>

Eso es asumiendo que su plantilla jQuery reside en la propia vista de Razor.

En el lado negativo, debe convertir cada argumento en una cadena antes de pasarlos al ayudante. Y, por alguna razón, pasando "${i+1}" para el ayudante se siente claramente mal.

Todavía no estoy seguro de si usaría ese tipo de enfoque en la producción, pero supongo que depende de la complejidad del marcado involucrado.

Respondido 28 ago 11, 00:08

Esto debería funcionar para plantillas simples y estoy de acuerdo en que no es correcto para plantillas complejas (en realidad, mi plantilla jQuery usa composición, lo anterior es un ejemplo simplificado). Hubiera sido bueno si las plantillas de Razor y jQuery compartieran una sintaxis común, excepto que eso molestaría a la multitud de PHP;) y muy pronto se encontrarían con limitaciones a medida que comience a usar construcciones de lenguaje más específicas. - Stefann

Puede representar el resultado de la búsqueda inicial con la misma plantilla de jquery en lugar de usar la sintaxis de razor, esto evita la duplicación. Podrías poner esto en la vista:

<script type="text/javascript">
    $('#resultTemplate')
    .tmpl(@group.ToJson()))
    .appendTo("#resultTemplate");
</script>

Inventé el método ToJson en el objeto de grupo. Podría ser un método que implemente en su modelo de vista o de lo que provenga el grupo var para serializar la colección a json.

Respondido 28 ago 11, 02:08

Es cierto, pero esto no es SEO. Habría hecho toda la funcionalidad de resultados de búsqueda en el lado del cliente si no fuera por esos malditos robots de búsqueda que no ejecutan JS;). Además, necesito que aparezca algo para los pocos visitantes sin JS. - Stefann

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