En este artículo, revisaremos el proceso de uso de JavaScript, desde una perspectiva basada en MVC, para manipular el DOM. Más específicamente, diseñaremos nuestros objetos JavaScript, sus propiedades y métodos, y sus instancias paralelas al comportamiento previsto de nuestras Vistas (lo que el usuario ve).
En cualquier punto del desarrollo de una página web, estamos usando un lenguaje que naturalmente promueve el desarrollo basado en clases o el desarrollo basado en objetos. En lenguajes fuertemente tipados como Java y C #, usualmente estamos escribiendo nuestras vistas en clases, dándoles el estado, el alcance y el contexto. Cuando trabajamos con lenguajes como PHP o motores de visualización más nuevos, como Razor para ASP.NET, nuestras vistas pueden simplemente ser marcas (HTML / CSS) combinadas con plantillas. Sin embargo, esto no significa que tengamos que cambiar nuestra percepción sobre cómo se comporta la vista como su propia entidad con estado..
Dentro de Views, estamos trabajando principalmente con HTML, que consiste en elementos anidados; estos elementos tienen atributos que describen cuál es su propósito semántico o cómo aparecen cuando se procesan. Luego, estos elementos tienen elementos secundarios o primarios que heredan / proveen en cascada (a través de CSS) y comportamientos de bloque / en línea. Estos elementos pueden verse naturalmente desde una perspectiva OOP (Programación Orientada a Objetos). Considere, por ejemplo, el siguiente marcado:
div.container border: 1px solid # 333; relleno: 5px; color rojo;
Sobre nuestra compañía
Como puede ver arriba, el encabezado heredó su propiedad de color de fuente de su contenedor primario a través del comportamiento CSS de la cascada. Este comportamiento es bastante similar al concepto de herencia en OOP. También podemos ver que el encabezado es un elemento secundario del contenedor, que hereda ciertas propiedades, según el comportamiento del elemento. Cuando vemos nuestros elementos desde esta perspectiva, tenemos una mejor definición de lo que pretendemos hacer con nuestros elementos de vista y podemos encapsular mejor los estilos y la funcionalidad..
Dentro de una vista, tendremos marcado. Sin embargo, este marcado puede tener vistas parciales anidadas como barras laterales, un encabezado, un pie de página, un carril derecho (o izquierdo) y una o más secciones de contenido. Todas estas vistas parciales deben considerarse como su propia entidad, capaz de tener su propio estado, contexto y alcance..
"Cuando concibe sus vistas y vistas parciales como objetos, hace que escribir su código del lado del cliente sea mucho más fácil".
Muchos desarrolladores tienden a escribir JavaScript desde un punto de vista de procedimiento o funcional, y a menudo se niegan a considerar las tendencias naturales que se ofrecen en los enfoques de desarrollo basados en vistas y en la creación de instancias paralelas (creando una nueva instancia de la vista cuando creamos una nueva instancia de un JavaScript objeto correspondiente a esa vista) cuando se trabaja en MVC Frameworks. A menudo es el caso que me encuentro con archivos JavaScript que son solo un método después de otro. Aunque este comportamiento funciona, y es común, no es muy eficiente para el mantenimiento, la depuración o la extensión del código actual o futuro cuando se trabaja de forma extensa con vistas..
Para alejarse de este hábito y comenzar a escribir un mejor código de comportamiento, cuando comience a diseñar las secuencias de comandos y los estilos de su Vista, siga estas reglas generales:
Considera el siguiente diagrama:
Por lo general, creo estilos y secuencias de comandos específicos para cada vista y luego tomo lo que necesito de las hojas de estilo principales y las bibliotecas de secuencias de comandos que he creado y que se usarían en muchas vistas. Esto también reduce la cantidad de código que se utiliza.
En este artículo, presentaremos la estructura de la página Acerca de nosotros en un sitio basado en MVC. Para comenzar, crearemos la estructura como se muestra arriba en el diagrama anterior. A partir de ahí, crearemos un objeto Acerca de, y comenzaremos a agregar métodos al prototipo. Primero, considera el siguiente diseño visual:
Este es un diseño muy lógico y comúnmente utilizado para una página web. Podemos segmentar nuestra página en objetos visuales separados. Para cada una de estas vistas, podemos crear un objeto lógico que se corresponderá con él. Generalmente omito la información repetitiva en el nombre de archivo o el nombre de clase que usa MVC para determinar el URI de la ruta y, en cambio, me quedo con algo que es fácil de mantener consistente.
Para las vistas de página, generalmente llamo a mis objetos de JavaScript por el nombre de la vista. Aquí hay un ejemplo de mi objeto AboutView:
// Ver nombre de archivo: AboutView.cs (.NET MVC 1.0), About.cshtml (.NET MVC 3.0), o AboutView.php (PHP) var About = function (pageTitle) this.pageTitle = pageTitle; // eventos vinculantes tan pronto como el objeto es instanciado this.bindEvents (); ;
En el ejemplo anterior, creamos un objeto JavaScript en el formato de función, lo que le da la capacidad de servir como un constructor de objetos para todos los métodos a los que se llama para la vista de. Al elegir este formato, podemos instanciar una nueva instancia de esta, tal como lo hacemos con nuestra vista Server-Side (diciendo nuevo AboutView ();
). Desde aquí, podemos asignar propiedades y métodos a este objeto. Para asignar métodos a este objeto, necesitaremos acceso al prototipo del objeto..
Los desarrolladores a menudo se ven frustrados por la elusividad (y la ambigüedad) del prototipo de objeto de JavaScript.
Los desarrolladores a menudo se ven frustrados por la elusividad (y la ambigüedad) del prototipo de objeto de JavaScript. Para muchos, puede ser confuso usar y entender y agrega otra dimensión a la codificación. A medida que JavaScript se vuelve más impulsado por eventos con los conceptos de HTML5, AJAX y web 2.0, JavaScript tiende a inclinarse naturalmente hacia el desarrollo de procedimientos que es fácil de desarrollar pero difícil de mantener, escalar y replicar..
Piensa en la palabra Prototipo como un nombre inapropiado por ahora. Cuando pienso Prototipo, Pienso en un "borrador" o en una base para la herencia, pero este no es exactamente el caso.
"En realidad, la mejor perspectiva para Prototype sería el puntero del objeto en la memoria".
Cuando creamos un objeto, instanciamos una nueva instancia de él. Cuando hacemos eso, creamos un lugar en la memoria al que se puede hacer referencia al objeto (recuerde, los objetos en JavaScript son tipos de referencia, tipos no primitivos; crear otra variable igual a ese objeto y luego cambiar sus valores cambiará el objeto original en el puntero). Cuando creamos un objeto, creamos una instancia de él y luego modificamos su "puntero" o Prototipo, agregamos campos y métodos a ese objeto en la memoria directamente (obviamente queremos agregar todas estas cosas antes de la creación de instancias).
Aquí hay un ejemplo de crear métodos en el Acerca de
prototipo del objeto:
var Acerca de = function (pageTitle) this.pageTitle = pageTitle; // eventos vinculantes tan pronto como el objeto es instanciado this.bindEvents (); ; var About.prototype.bindEvents = function () // Contexto actual: 'this' es el objeto About // Coloque todos sus enlaces de eventos en un lugar y llámelos // en sus propios métodos según sea necesario. $ ('ul.menu'). en ('clic', 'li.search', $ .proxy (this.toggleSearch, this)); ; var About.prototype.toggleSearch = function (e) // Alternar la función de búsqueda en la página;
Como puede ver arriba, hemos contenido las propiedades del objeto Acerca de dentro del constructor, hemos creado un único punto de referencia para eventos de enlace (en este caso estamos usando jQuery para crear los enlaces de eventos, pero puede usar cualquier marco o JavaScript en sí), y han colocado el método toggleSearch en el prototipo del objeto Acerca de para contener ese método a ese objeto. También hemos llamado al bindEvents ()
Método en el objeto para que se llame en instanciación..
Ahora, considere el siguiente código para la vista parcial de la barra lateral:
var pSidebar = function (pageTitle) this.pageTitle = pageTitle; // llamar al método bindEvents en la instanciación del objeto pSidebar. // esto unirá los eventos al objeto this.bindEvents (); ; var pSidebar.prototype.bindEvents = function () // contexto actual: 'this' es el objeto Sidebar $ ('ul.menu'). en ('click', 'li.has-submenu', $ .proxy ( this.toggleSubMenu, this)); $ ('input # search'). on ('click', $ .proxy (this.openSearch, this)); ; var pSidebar.prototype.toggleSubMenu = function (e) // alternar los submenús // contexto actual: 'este' es el pSidebar obj;
NOTA: Llamé al objeto pSidebar
porque esto es un vista parcial, No es una vista completa. Esta es mi preferencia para distinguir entre los dos, pero aclara las cosas..
La belleza de usar este enfoque es que podemos usar los mismos nombres de métodos que usamos en el objeto Acerca de y no tendremos conflictos. Esto se debe a que estos métodos están vinculados al objeto prototipo en sí, no el espacio de nombres global. Esto simplifica nuestro código y permite una especie de "plantillas" para futuras secuencias de comandos.
Una vez que haya creado sus objetos, llamarlos es simple. Ya no necesita depender de su marco para desencadenar eventos cuando su documento está cargado o listo. Ahora, simplemente puede crear una instancia de su objeto y sus eventos serán vinculados y ejecutados según sea necesario. Por lo tanto, vamos a instanciar nuestra Acerca de
objeto:
Dentro de la vista en la que llamaría scripts específicos para su vista (dependiendo de su lenguaje de plantillas), simplemente llame a una nueva instancia de su objeto e incluya el archivo de la siguiente manera:
Como puede ver, pasé el título de la página para la vista (lo que puede ser cualquier argumento para cualquier necesidad, incluso Datos del modelo. Esto le brinda un excelente contexto sobre los datos de su modelo y le permite manipular esos datos en JavaScript muy fácilmente.
Como tu Acerca de
Objeto, llamar a tus vistas parciales es igual de fácil. Recomendaría encarecidamente llamar a nuevas instancias de los objetos de JavaScript de vista parcial dentro del constructor del objeto, esto garantiza que solo los esté llamando según sea necesario y que estén colectivamente en un solo lugar..
var Acerca de = function (pageTitle) this.pageTitle = pageTitle; // asignando una nueva instancia de la vista parcial de la barra lateral para consultarla más adelante this.sidebar = new pSidebar (pageTitle); // NOTA: Si no necesita hacer referencia a una vista parcial después del hecho, // simplemente puede crear una instancia de ella sin asignarla dentro del constructor del objeto, así: new pSidebar (pageTitle); // haciendo lo mismo para la vista de pie de página parcial this.footer = new pFooter (); // eventos vinculantes tan pronto como el objeto es instanciado this.bindEvents (); ;
Como puede ver, al hacer referencia al objeto de la barra lateral como una propiedad local del objeto Acerca de, ahora vinculamos esa instancia, que es un comportamiento muy natural, esta instancia ahora es la barra lateral de la página..
Si no necesita hacer referencia a una vista parcial después del hecho, puede simplemente crear una instancia de ella sin asignarla dentro del constructor del objeto, de esta forma:
var Acerca de = function (pageTitle) this.pageTitle = pageTitle; nueva pSidebar (pageTitle); // eventos vinculantes tan pronto como el objeto es instanciado this.bindEvents (); ;
Desde aquí, todo lo que tenemos que hacer es agregar otro script a nuestros scripts llamados en nuestra vista:
Una vez que esta estructura está en su lugar, podemos adaptar nuestro objeto JavaScript para que coincida con nuestra vista y aplicar los métodos necesarios a ese objeto para mantener el alcance. Al crear un objeto de vista paralela y trabajar con el prototipo de ese objeto, vemos los siguientes beneficios:
A medida que el patrón de diseño de MVC continúa siendo más popular en el mundo del diseño, el desarrollo de objetos de JavaScript para acompañar la manipulación de elementos DOM cambiará para adaptarse más a la manipulación específica de la vista y del evento. Al adaptar nuestros objetos de JavaScript para crear una instancia en paralelo con nuestras Vistas, podemos tener una relación de estado a mano entre los dos, una que es simétricamente de buen gusto, fácil de seguir, fácil de mantener y perfecta para la expansión como la vista crece o cambia, creando una relación permeable y expandible entre el marcado y las secuencias de comandos.
Al utilizar un Prototipo de Objeto, podemos mantener un contexto preciso en el objeto de script de nuestra Vista y expandir ese objeto con un marco de mente de desarrollo repetitivo. Luego podemos replicar este formato a través de nuestras vistas parciales, lo que nos ahorra tiempo, capacidad mental y riesgo de errores y comportamiento inesperado.