OO Javascript: ¿debería dejar que una clase se agregue al DOM o dejar que devuelva un elemento para luego agregarlo al DOM?
Frecuentes
Visto 163 equipos
7
Estoy practicando con OO Javascript, creando una especie de aplicación web para ver Manga (cómics)
En este momento tengo algunas clases:
- Resultado de búsqueda
- Manga (generado a partir de datos del resultado de búsqueda)
- Capítulo (contenido dentro de Manga)
- Página (contenida dentro del Capítulo)
- Imagen (contenida dentro de la página)
Agrego el resultado de la búsqueda al DOM generando el html del elemento y luego lo agrego con jQuery.
Aquí es donde entra mi pregunta:
¿Debería generar html (o un elemento jQuery DOM) y devolver esto desde una función en la clase y luego agregar este elemento fuera de la clase o sería más inteligente darle a la clase una referencia al contenedor en el que debería poner elementos y dejarlo? poner los elementos en ese contenedor agregando?
¿Así que esto?:
function(data, result, response) {
var
$resultContainer = $('<div/>', {class: 'row-fluid'}),
maxResults = 10;
for(var i in data) {
if(i == maxResults) {
break;
}
data[i].manga = Manga(data[i]);
var res = new SearchResult(data[i]);
res.setMyContainerElement($resultContainer);
res.addResultToDOM();
}
}
¿O esto?:
function(data, result, response) {
var
$resultContainer = $('<div/>', {class: 'row-fluid'}),
maxResults = 10;
for(var i in data) {
if(i == maxResults) {
break;
}
data[i].manga = Manga(data[i]);
var res = new SearchResult(data[i]);
$resultContainer.append(res.getHTML());
}
}
En estos ejemplos, la variable "datos" son datos de una llamada AJAX que devuelve una cadena JSON que contiene los resultados, actualmente no hay límite para la cantidad de resultados devueltos, por lo que la configuré codificada, agregaré esto cuando entrar en más detalles en el lado del servidor, pero por ahora esto estaría bien ya que trabajo en el front-end.
Si se requiere información adicional, hágamelo saber, con gusto la actualizaré con cualquier información que se me haya pasado por alto o que sea necesaria, si está disponible.
4 Respuestas
3
Mover comentarios para responder, ya que la pregunta se basa principalmente en opiniones y es posible que se cierre :)
En teoría, el código es más reutilizable si devuelve la estructura de la función de trabajador y deja que la función de administrador que lo llamó decida qué hacer con él. es decir, "los trabajadores trabajan y los gerentes administran". Pasar el contenedor por el árbol de código agrega dependencias :)
No es fácil, pero el mejor enfoque es pensar que cada función se está escribiendo para otra persona y que desea ser lo más útil posible.
Si cambia la estructura de datos, por supuesto que necesitará refactorizar, pero eso es preferible a mover la toma de decisiones/dependencias a un nivel inferior. En todo caso, desea verse obligado a revisar el código de alto nivel que depende de la forma de los datos.
Con respecto a los parámetros que son dependencias:
Los parámetros de las funciones son sólo más malo cuando hacen que la función tome decisiones (lo que se conoce como acoplamiento de comandos). Los valores para búsqueda y procesamiento son Gooder usos para parámetros :)
contestado el 28 de mayo de 14 a las 14:05
2
En OOP, sería al revés devolver una Vista desde un modelo, por lo que recomendaré NO hacer eso.
Lo que realmente está buscando aquí es un sistema de plantillas: una plantilla significa que tiene una parte de HTML en algún lugar de su página, con 'marcadores de posición' de valor, y cuando esté listo para imprimir su SearchResult, la plantilla se clona , colocado en la página, y los 'marcadores de posición' se rellenan con los valores reales (por ejemplo, el título del cómic, la imagen de portada, etc.)
Hay muchos sistemas de plantillas de JavaScript. La parte superior de mi cabeza:
- BigoteJS
- Manillar
- polvojs
- KnockoutJS
Tengo experiencia con KnockoutJS, así que puedo darle una vista previa de cómo se vería en el código (vea las etiquetas de 'enlace de datos', manejadas por KnockoutJS automáticamente):
<body>
<!-- The contents of this DIV will be repeated for each 'manga' in 'mangas' -->
<div class="manga-list" data-bind="forEach: mangas">
<!-- This paragraph will be updated with the manga's 'title' value -->
<p class="manga-title" data-bind="text: title"></p>
<!-- This paragraph will be updated with the manga's 'cover' value (as src) -->
<img class="manga-cover" data-bind="attr: {src: cover}" />
</div>
</body>
<script>
var viewModel = {
mangas: ko.observableArray();
};
ko.applyBindings(viewModel);
// ...
// some code where you get your SearchResult
// ...
for (var i = 0; i < searchResult.length; i++)
{
viewModel.mangas.push(searchResult[i]);
}
// When the FOR loop above runs, your HTML is automatically updated.
<script>
No estoy seguro si estoy 100% correcto en la sintaxis anterior (tal vez me falta un carácter o algo así), pero es, con mucho, mi biblioteca favorita de encuadernación/plantillas, y es bastante sencilla de usar.
contestado el 28 de mayo de 14 a las 14:05
Uh new SearchResult(data[i])
se parece mucho a una vista, donde data[i].manga = Manga(data[i])
es el modelo La pregunta es si una Vista (podría usar plantillas o no) debería aplicarlas en un elemento DOM dado o debería devolver un elemento DOM. - Iceberg
Vaya, mi mal. Bueno, tal vez esto permita que otros visitantes descubran el poder de las bibliotecas con plantillas; Lo siento, esto resultó irrelevante. - hbCyber
En mi código, no he aplicado nada parecido a una estructura MVC, todavía soy bastante nuevo en este tipo de estructuras de programación OO, por lo que aplicarlas a Javascript OO está más allá de mis capacidades en este momento, si estuvieras implicando que tenía un MVC subyacente estructura para el manejo de estas clases y su salida. Las clases son controladores, vistas y modelos, todo al mismo tiempo, ¿sería más inteligente implementar una estructura MVC para este tipo de código (dada mi experiencia) o sería demasiado complicado y/o sería un salto demasiado grande en ¿este punto? Todavía estoy en las primeras etapas del proceso de esta solicitud. - Magikaas
Bueno, me parece que ya tienes 'clases' modelo (poniendo comillas porque en JavaScript el concepto es un poco flojo), pero creo que usar un sistema de plantillas no será demasiado difícil de aprender (KnockoutJS tiene uno de los mejores y más ¡documentación concisa!) y realmente, realmente le ahorrará mucho tiempo y dolores de cabeza a largo plazo. Es prácticamente un hecho que entrará en un escenario en el que es útil: tiene datos almacenados en objetos JS y desea mostrarlos a través de HTML, es probable que suceda. Eche un vistazo a mi código de ejemplo, esencialmente Knockout se reduce a eso. - hbCyber
0
¿Debo generar html o un elemento jQuery DOM?
Elemento DOM, definitivamente.
¿Debería devolver esto desde una función en la clase y luego agregar este elemento fuera de la clase o sería más inteligente darle a la clase una referencia al contenedor en el que debería colocar los elementos?
Ambos enfoques están bastante bien. Cuál elegir debería depender de si su instancia de clase lo hace ocupar el contenedor completo.
Si es así, está bien pasar el elemento contenedor al constructor y dejar que el código de la clase haga lo que quiera con él. La mayoría de los widgets funcionan así, y el método es utilizado favorablemente por los complementos de jQuery que se llaman a los elementos de todos modos.
Sin embargo, si su clase crea un solo elemento y no puede estar seguro de qué hacer con él, sería mejor devolverlo. Como usted dice,
deja que ponga los elementos en ese contenedor agregando
no lo hace muy reutilizable. ¿Qué pasa si ahora quieres ponerlos en el contenedor anteponiéndolos? La clase no sabe nada de esto, simplemente debería cederte su elemento. Aquellos .setMyContainerElement()
e .addResultToDOM()
Los métodos no son más que código repetitivo, envolviendo los métodos jQuery equivalentes. Mejor devolver la colección jQuery y dejar que la persona que llama haga .appendTo($containerElement)
(o .prependTo($containerElement)
?).
contestado el 28 de mayo de 14 a las 14:05
Cuando dije agregando, era un ejemplo, podría agregar, anteponer, reemplazar, lo que sea necesario, dependiendo de lo que la función quiera hacer. Pero veo lo que quiere decir, también podría usar append en lugar de addResultToDOM, pero tuve que darle un nombre razonablemente descriptivo si tuviera que agregarlo como una función a la clase, por ahora he vuelto a devolver un jQuery elemento DOM, que luego puedo usar para el contenido de mi corazón en cualquier código usando dicha clase. - Magikaas
Bueno, el punto es: ¿Su clase sabe lo que se requiere, o necesitaría cubrir todas las posibilidades que la persona que llama podría querer? - Iceberg
En la actualidad, solo necesitaría devolver un solo elemento DOM, que representa el resultado de la búsqueda, que luego podría agregarse a un contenedor para estos resultados de la búsqueda. Entonces, ¿supongo que esto implica que tiene que cubrir todas las posibilidades? No he pensado demasiado en la implementación y todavía estoy bastante temprano en el desarrollo, configurando la estructura de mis clases y sus respectivas funciones. - Magikaas
Al devolver el elemento DOM, la persona que llama (que usa SearchResult, es decir, la función de ejemplo que publicaste en tu pregunta) tiene implícitamente todas las posibilidades, puede hacer lo que quiera con él, incluso las cosas en las que no habías pensado. No hay código en su SearchResult
Se requiere clase para eso. - Iceberg
0
Tiendo a ver vistas personalizadas como si fueran elementos DOM nativos y esto se alinea muy bien con los componentes web.
Al instanciar un nuevo elemento DOM, no es el elemento en sí mismo el que tiene la responsabilidad de representarlo en su contenedor; de lo contrario, el elemento necesitaría conocer el contexto en el que se representa y esa sería una forma muy mala de acoplamiento.
Como dijo @Bergi, es menos dañino para permitir que el componente se represente en su contenedor si está diseñado para ocupar todo el espacio del contenedor. Aún así, esta práctica a menudo conduce a tener un elemento contenedor adicional con el único propósito de posicionar la vista.
En resumen, diría que si el código de su vista no está diseñado para mejorar un elemento existente, debe evitar darle la responsabilidad de mostrarse en su contenedor. La flexibilidad que obtiene al dejar la tarea de representación en manos del código de llamada supera fácilmente la complejidad añadida.
PS: DOM vs HTML strings = DOM
a menos que haya implicaciones significativas en el rendimiento y esté dispuesto a sacrificar la flexibilidad.
contestado el 28 de mayo de 14 a las 16:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript jquery dom or haz tu propia pregunta.
En teoría, el código es más reutilizable si devuelves la estructura del función del trabajador y deja que el función de gerente que lo llamó decidir qué hacer con él. es decir, "los trabajadores trabajan y los gerentes administran". Pasar el contenedor por el árbol de código agrega dependencias :) No es fácil, pero el mejor enfoque es pensar que cada función se está escribiendo para otra persona y desea ser lo más útil posible. - iCollect.it Ltd
Eso es lo que también pensé y lo he hecho hasta ahora, pero pensé en lo que sucedería si, por alguna razón loca, tuvieras que cambiar la forma en que funcionaba la clase y hubiera generado algo que no se esperaría por cualquier código. estaba usando la salida de la clase, esto significaría una gran cantidad de refactorización. Editar: Aunque por lo general debe evitar esto, ya que hay mucho código que depende de la salida de ciertas funciones. Edit2: @TrueBlueAussie Tiene razón, de esa manera funciona más como una API, o una fábrica de la vida real, que produce partes para ser utilizadas por procesos externos. - Magikaas
Si cambia la estructura de datos, por supuesto que necesitará refactorizar, pero eso es preferible a mover la toma de decisiones/dependencias a un nivel inferior. En todo caso, desea verse obligado a revisar el código de alto nivel que depende de la forma de los datos. - iCollect.it Ltd
Buen punto. En todo caso, debería hacer que cualquier código que use la salida de estas clases sea más flexible, mientras mantengo la 'dependencia' de esperar un elemento jQuery DOM o una cadena html, no puede tener en cuenta todo al crear este tipo de funciones: Magikaas
Los parámetros de las funciones son sólo más malo cuando hacen que las decisiones sean tomadas por la función (conocida como
command coupling
). Los valores para búsqueda y procesamiento son Gooder usos para parámetros :) - iCollect.it Ltd