2011-07-05 9 views
6

Estoy muy familiarizado con JavaScript y OOP, pero no estoy familiarizado con el diseño de clases JS que se utilizan para programar la interfaz de usuario (HTML). He buscado un poco pero no he encontrado patrones prevalentes.¿Cuáles son las mejores prácticas para diseñar clases de JavaScript que representan objetos de interfaz de usuario en el DOM?

Digamos que quería crear dinámicamente objetos parecidos a paneles (similares a los paneles de Microsoft Windows). Cada objeto necesita un contenedor, un área de encabezado que podría incluir una etiqueta de texto y un botón de cerrar que tiene un controlador de evento de clic. Además de una representación DOM (HTML), el objeto también tendría una representación de objetos JavaScript (variables y métodos). Aquí hay una forma en que lo he intentado:

// 
// Window class 
// 
var Window = function(params) { 
    this.testMethod = function() { 
     console.log('test'); // just an example 
    } 

    this.windowDiv = document.createElement('div'); 
    this.windowDiv.style.width = params.width + 'px'; 
    this.windowDiv.style.height = params.height + 'px'; 
    this.windowDiv.style.position = 'absolute'; 
    this.windowDiv.style.top = '30px'; 
    this.windowDiv.style.left = '30px'; 
    this.windowDiv.style.border = '1px solid #000'; 

    this.headerDiv = document.createElement('div'); 
    this.headerDiv.style.width = '100%'; 
    this.headerDiv.style.height = '30px'; 
    this.headerDiv.style.background = '#bbb'; 
    this.headerDiv.style.borderBottom = '1px solid #000'; 
    this.headerDiv.innerHTML = params.title; 

    this.buttonDiv = document.createElement('div'); 
    this.buttonDiv.style.width = '30px'; 
    this.buttonDiv.style.height = '18px'; 
    this.buttonDiv.style.position = 'absolute'; 
    this.buttonDiv.style.top = '0px'; 
    this.buttonDiv.style.right = '5px'; 
    this.buttonDiv.style.textAlign = 'center'; 
    this.buttonDiv.style.background = 'red'; 
    this.buttonDiv.style.border = '0px 1px 1px 1px solid #000'; 
    this.buttonDiv.innerHTML = 'x'; 
    this.buttonDiv.addEventListener('click', function(e) { 
     document.body.removeChild(e.target.parentNode.parentNode); 
    }, false); 

    this.headerDiv.appendChild(this.buttonDiv); 
    this.windowDiv.appendChild(this.headerDiv); 
    document.body.appendChild(this.windowDiv); 
} 

// Initialize 
var myWindow = new Window({ 
    width: 400, 
    height: 200, 
    title: 'My Window' 
}); 
myWindow.testMethod(); 

Esto no se siente "correcto". Otro enfoque podría ser tener un método render() y usarlo para separar el código de generación HTML. Parece incómodo que el objeto JS contenga múltiples objetos HTML anidados dentro de él. ¿Debería pasar las etiquetas anidadas a través de innerHTML?

Así que tengo curiosidad ... ¿cuál es el mejor enfoque aquí? ¿Cuál es la mejor manera de diseñar clases que tengan código DOM (objetos HTML y estilo) y variables y métodos tradicionales? ¿Hay alguna manera de usar prototipos para estos objetos HTML? Incluso se puede imaginar en este ejemplo que también hay una clase de WindowManager que contiene objetos de Windows instanciados, ayuda a administrarlos y crea otros nuevos. Y también podría tener una representación HTML.

Algunas de las anteriores pueden manejarse con CSS estático y aplicar ID/clases para limpiar parte del código, pero digamos que el posicionamiento y el tamaño deben lograrse programáticamente (para manejar el cambio de tamaño, arrastrar y soltar, etc.)

No me interesan las soluciones de nivel de marco que podrían proporcionar ExtJS, jQuery, etc. Quiero saber cuáles son las mejores prácticas para el código local. De hecho, me interesaría saber cómo los ingenieros de dichos frameworks diseñan sus clases de UI.

+0

jQuery y jQueryUI son de código abierto. Siempre puedes mirar;) https://github.com/bmsterling/jquery-ui – AlienWebguy

+1

John Resig (jQuery) ofrece la discusión de diseño más completa que creo que he visto. Tienes que comenzar allí. – dkretz

Respuesta

2

Para la parte HTML del objeto, puede usar una plantilla para definir la estructura HTML del componente, conectando cualquier dato que sea necesario cuando se inicializa el componente. Hay muchas maneras de implementar la función de plantilla, eche un vistazo a underscore.js para ver un ejemplo.

Para los estilos, pondría los valores predeterminados en la hoja de estilos. No importa si necesitan ser modificados más tarde a través de javascript, eso seguirá funcionando incluso si están definidos en css. La única información que debe estar en el componente es el comportamiento predeterminado de los diversos eventos que ese componente activa.

También podría considerar la creación de una cadena prototipo simple para poner propiedades comunes dentro de las "clases" base (entendiendo que javascript no tiene clases reales), nuevamente consulte underscore.js para un ejemplo de la función extender que hace esto, entre otras implementaciones que se pueden buscar en Google.

Al final, lo único que importa es que su código es fácil de usar y comprender, y funciona bastante bien. También puede regresar y mejorar partes que no funcionan tan bien, o reorganizar el código en módulos.

+0

Gracias Jason. He echado un vistazo a esto y es muy útil. Voy a tocarlo un poco más este fin de semana para ver lo que realmente puede hacer :) También me llevó a la discusión de John Resig sobre micro-plantillas que también fue esclarecedor. – skyline3000

0

Backbone.js es una buena opción para sus necesidades declaradas:

http://documentcloud.github.com/backbone/

almaceno HTML dentro de plantillas y cargarlos al elemento visual de que el controlador gestiona (un div creado de forma dinámica para cada instancia) ..esto me da elementos reutilizables html y métodos y propiedades de la interfaz de usuario que son específicos para cada instancia de la interfaz de usuario.

Cuestiones relacionadas