2011-01-15 13 views
8

Soy un desarrollador web y fui codificador durante mucho tiempo. Pero nunca he usado una arquitectura MVC pura. Ahora comencé mi propio proyecto y decidí hacer html-css y contratar un codificador. Elegimos el popular PHP-MVC-framework.MVC: ¿cuánto código debería haber en una vista?

Se hacen los primeros pasos, algunas páginas están codificadas. Y después de mirar el resultado, tengo la pregunta ... ¿cuánto código debe haber en las plantillas (Vista)?

Por ejemplo, aquí es un archivo de plantilla:

<?php $this->load->view('header'); ?> 
<?php $this->load->view('banner'); ?> 

<div id="items"> 
<?php 
for($i=0; $i<count($main); $i++) { 
    echo '<div class="item"> 
     <div class="name">'.$main[$i]['name'].'</div>'; 
    if($main[$i]['icq']=='') { } 
     else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; } 
    echo '</div>'; 
} 
?> 
</div> 

<?php $this->load->view('footer'); ?> 

¿Cree que hay demasiado código en esta plantilla o es normal?

Respuesta

9

No creo que lo que estás tratando de lograr en la vista sea demasiado lógica, pero creo que debería limpiarse un poco.

Algo así como:

<?php foreach($main as $item): ?> 
<div class="item"> 
    <div class="name"><?php echo $item['name']; ?></div> 
    <?php if($item['icq']): ?> 
     <div class="phone"><?php echo $item['phone']; ?></div> 
    <?php endif; ?> 
</div> 
<?php endforeach; ?> 

me parece que sea mucho más fácil de leer, y lo hace el mismo trabajo. Tampoco creo que sea difícil para un no codificador modificar, que en última instancia es el objetivo de una vista.

+4

Si short_tags (php.ini) está activado, incluso se podría utilizar "<= $ item [ 'teléfono']?>" En lugar de

+3

Me discutiendo si debe o no poner esto en, pero personalmente no me gusta depender de etiquetas cortas - nunca se sabe cuando alguien va a apagarlos en usted, y entonces usted se encontrará con un mundo de problemas. – sevenseacat

+1

No consumo ellos tampoco ... pero yo creo que en CodeIgniter que funcionarían sin importar si están desactivados Apache ... – rabidmachine9

0

pienso como James, demasiado código, pero se puede añadir una variable de matriz a los get_items() función, para controlar el prefijo y sufijo de cada elemento, algo así como:

$options = Array('item_prefix' => '<div class="item">', 'item_suffix' => '</div>'...) 
echo get_items(); 
0

Sus puntos de vista deben Definitivamente contiene la mayoría de las etiquetas html, por lo que no creo que una función get_items deba colocarse en otro lugar. Simplemente limpie sus plantillas un poco y trabaje con la sintaxis de bucle alternativo sugerida por Karpie. También podría pensar en utilizar un motor de plantillas existente como Twig pero con eso las vistas también deben contener algunas referencias a sus datos ... Lo que quiere lograr es que los no codificadores puedan editar sus archivos html sin tener que entender demasiada lógica de scripting.

2

Cuando las plantillas necesitan una gran cantidad de la lógica es que podría ser útil introducir el ViewModel pattern

La lógica que determina cuando un cierto bloque se muestra se coloca en el modelo de vista.

Ejemplo
Un fragmento de plantilla:

<?php if($item['show_phone_number']): ?> 
    <div class="phone"><?php echo $item['phone_number']; ?></div> 
<?php endif; ?> 

una vista de modelo fragmento:

$item['show_phone_number'] = $item["icq"] == ''; 
+0

Esta respuesta está infravalorada: el patrón ViewModel es lo que debe examinarse aquí. – Jimbo

1

respuesta corta:

Tan poco como es de forma viable posible.

16

La primera respuesta fue realmente acertada, pero el usuario la eliminó (probablemente debido a la presión de grupo). Básicamente, no desea ninguna lógica en su plantilla. En un mundo ideal, tenía una etiqueta para todos los datos del modelo, pero como estamos en un mundo HTML, no existe, por lo que debe usar XSLT o usar ViewHelpers.

Centrémonos en el enfoque de ViewHelper.

Esto es difícil de mantener:

<div id="items"> 
<?php 
for($i=0; $i<count($main); $i++) { 
    echo '<div class="item"> 
     <div class="name">'.$main[$i]['name'].'</div>'; 
    if($main[$i]['icq']=='') { } 
     else { echo '<div class="phone">'.$main[$i]['phone'].'</div>'; } 
    echo '</div>'; 
} 
?> 
</div> 

Y no va a ser mejor si se reemplaza el PHP con Smarty. Esto es fácil de mantener:

<div id="items"> 
    <?php echo itemlist($items, 'template.htm') ?>; 
</div> 

Por debajo de la pregunta ahora eliminado, hubo una commentor objetar este "código no es fácil de mantener para los no programadores porque ahora no saben donde se define y ITEMLIST Que hace." pero eso es un galimatías completo. Piensa en ello un segundo.

Por un lado, afirman que los no codificadores tendrán problemas con una llamada a una función simple, pero por otro lado esperan que entiendan la mezcolanza del código PHP mezclado con HTML. A un diseñador no le importa la lógica de presentación, sino solo la presentación real. La salida.

Una llamada a una sola función dice claramente: "aquí hay una lista de elementos", que es mucho más fácil de comprender que "aquí hay un for que hace eco de un div y tal vez algo más si se da icq". Una llamada a función es tan buena como una etiqueta. Tiene entradas y salidas claramente definidas. Cómo logra que la salida sea irrelevante para cualquier persona que no sea el desarrollador.

Your ViewHelper encapsula la lógica de la presentación. Es un fragmento que puede volver a utilizar en todas sus Vistas. Eso es mucho más fácil de mantener que copiar y pegar toda esa lógica una y otra vez cuando sea necesario. En el ejemplo anterior, hay dos argumentos al ayudante:

  • artículos $ es una matriz o de otro tipo transitable la celebración de sus datos de artículos reales
  • 'template.htm' es el nombre de la plantilla que sirve para hacer los datos

Haré que el segundo sea opcional, porque supongo que siempre será la misma plantilla. Pero dado que el comentarista se quejó de que el no codificador no sabría dónde mirar, sentí que era necesario mostrar cuán fácil es decirle al no codificador a dónde mirar.

function itemlist($items, $template = './templates/itemlist.htm') { 
    ob_start(); 
    foreach($items as $item) { 
     include $template; 
    } 
    return ob_get_flush(); 
} 

Puede haber enfoques más eficientes para resolver la inclusión de la plantilla. La idea principal debe ser clara sin embargo. Ocultar la lógica de presentación de la plantilla real. Su "template.htm" se vería así:

<div class="item"> 
    <div class="name"><?php echo $item['name'] ?></div> 
    <?php echo contact($item, 'icq' 'phone'); ?> 
</div> 

No if y elses. Sin concatenaciones de cadenas o llaves. La lógica para decidir cómo contactar al usuario también está oculta en un ViewHelper. Todo lo que no codificador debe saber ahora son los argumentos para los ViewHelpers y eso es tan fácil como saber qué atributo escribir en una etiqueta. Deles una hoja de trucos si es necesario.

Información relacionada:


EDITAR

Debido a los dos comentarios a continuación que decidió ampliar esta respuesta. Lo anterior no es abstracción por el bien de la abstracción.Es para reutilización y mantenibilidad. Ya lo señalé anteriormente pero permítanme explicarlo aquí otra vez.

En realidad, me resulta extraño objetar el uso de ViewHelpers porque tendrá "tener presentación en dos lugares" pero no se quejará de separar encabezado, pancarta y pie de página. Es lo mismo. Aísla partes que son reutilizables y las coloca en sus propias plantillas. Separar la lógica de la plantilla en ese paso es simplemente el siguiente paso natural para lograr aún más capacidad de mantenimiento.

Una plantilla de vista que contiene lógica es efectivamente una secuencia de comandos y no una plantilla. Cualquier plantilla de vista que contenga la lógica para ensamblarse está condenada a repetirse. Esto podría no ser un problema en sitios pequeños, pero si está trabajando en un sitio con un par de docenas o incluso cientos de vistas y widgets, si no se resumen estas partes, se duplicará el código. Pon toda la lógica en la plantilla y rápidamente se convertirá en un enredo de c & marcado p'ed mezclado con condicionales. Para cualquier duplicación, duplicará el tiempo que lleva cambiarla. Agregue estilos en línea y Javascript molesto y se encuentra en un infierno de mantenimiento.¹

Si utiliza OOP para las otras partes de su aplicación, ¿por qué iría de procedimiento en su opinión? Si entendió que debe separar Javascript y CSS de su HTML, ¿por qué debería mezclar PHP en su plantilla? No tiene sentido. El fragmento de código de OP es un script y no una plantilla. Como tal, es el dominio del desarrollador. Y debido a eso aplica todas las buenas prácticas que aplica a otras partes de su aplicación también. Y eso incluye aislar la lógica en funciones y/o clases.

De acuerdo, un diseñador que busque un guión podría no saber de inmediato lo que está sucediendo. Pero, de nuevo, es posible que tampoco lo sepa una vez que empiece a agregar funciones PHP nativas. ¿Qué está haciendo mb_strimwidth? ¿Y substr? ¿Cuál es esa construcción ?:? Mientras más PHP real agregues, más difícil será leer para los que no sean desarrolladores.

Si desea que los diseñadores trabajen en plantillas, no les dé scripts. Dales plantillas. Y si lo hace, aísle la lógica de la misma y reemplácela con llamadas a funciones fáciles de comprender. Use nombres de funciones que comuniquen claramente lo que hace la función. Entonces, el diseñador solo necesita saber si "Utilizo esto con esa entrada, siempre obtendré esa salida. No me importa cómo llegue a ser esa salida. Se lo dejo al desarrollador".

El aislamiento de la lógica en funciones (o clases) también le brinda la ventaja inmediata de poder probar la lógica utilizada para representar partes específicas en esa página de forma aislada. No tiene que configurar todo el entorno necesario para crear una página, sino simplemente pasar la entrada requerida y afirmar su salida (es por eso que la función almacena la cadena en lugar de emitirla por cierto).

¹ Para aquellos de ustedes que piensan que esto no es un problema, les recomiendo encarecidamente encontrar una aplicación heredada que realmente mantenga toda la lógica en la plantilla de vista. Intenta cambiar algunas cosas. Una vez que haya tenido el placer de comer a través de 2500 líneas de código de spaghetti con al menos 500 caracteres cada una y que contengan una mezcla de repetidos PHP, HTML, CSS y JavaScript, sabrá de lo que estoy hablando.

+5

Veo esto como una abstracción por el bien de la abstracción. Estoy a favor de separar la presentación y el código comercial, pero ahora tienes una presentación en dos lugares ('template.htm', y donde sea que estés definiendo' contact() '), y salida de almacenamiento en búfer para ... ¿qué? No debería haber lógica de negocios en una vista, sí. La lógica de presentación es completamente diferente. – sevenseacat

+1

Totalmente de acuerdo, está moviendo la lógica de vista de la vista, mi pregunta es ¿por qué un "no codificador" estaría mirando esto de todos modos? La mayoría, si no todos los diseñadores que valen la pena, entienden el concepto de un si y un foreach. En realidad, es más confuso e impredecible ver una llamada de función en una vista. – jondavidjohn

1

Ver no es una plantilla.

O al menos, no debería ser una plantilla. Las vistas son generalmente una instancia de clases, que son responsables de tratar con la lógica de presentación. Hacen malabares con varias plantillas y deciden cuál usar y qué datos pasan a ellas.

Pero CI no tiene nada de esto.Básicamente está atrapado con una plantilla, que pretende ser "Ver", yy instancias de ActiveRecord, que le dicen que son "Modelos". Demonios ... en MVC adecuado, el Modelo no es ni siquiera una clase específica, sino una capa de aplicación.

En largo plazo, esta situación obligará tanto lógica de presentación y la lógica de negocio en el controlador, mientras que al mismo tiempo, producir y difíciles de mantener plantillas y clases ActiveRecord.

Cuestiones relacionadas