ember.js

¿Ember.js alienta demasiados controladores?



(2)

Creo que decir que Ember alienta demasiados controladores es como decir que Javascript alienta demasiadas funciones. Sí, puedes volverte loco con la proliferación de cualquiera. O puede hacer lo contrario, y hacer que funcione exactamente como lo necesita. En general, recuerde siempre que su aplicación debe ser exactamente tan compleja como debe ser, y no más. No es necesario usar una arquitectura o patrón determinado solo porque lo usó un codificador famoso, ni siquiera porque parece ser "la forma de Ember". Incluso las "cosas buenas universales" como Separation of Concerns, MVC, etc. son principios y modelos que debe tratar de comprender plenamente y luego utilizar en la medida en que satisfagan sus necesidades. Creo que la capacidad de romper selectivamente las reglas y los patrones por las razones correctas es mucho más una señal de un gran pirata informático que la devoción servil al dogma de los dioses programadores. Esto es un oficio, no una religión. (Pero YMMV. Tal vez haya un círculo especial de infierno reservado para programadores como yo. Estoy apostando en contra de eso).

Específicamente para Ember, tiendo a usar Controladores en torno a mis modelos de datos y / o en torno al flujo de trabajo de un usuario en particular, en lugar de en cada vista. Luego use los administradores de enrutamiento / estado como el pegamento entre sus vistas, y generalmente uso los administradores de eventos en las vistas para manejar los eventos del navegador dentro de cada vista, incluido el envío de instrucciones al enrutador. Entonces, si tengo una aplicación que gira en torno a, digamos, Clientes y Productos, tendré un controlador para cada uno, tal como lo hago en Rails. Esto dará como resultado que cada controlador tenga más funciones y propiedades computadas de las que algunas personas prefieren tener en un solo lugar. También significa que no necesariamente puedo reutilizar mis vistas en otro contexto, porque están cableadas al controlador. Y sí, esto es pobre separación de preocupaciones. Pero eso no es un bien absoluto si causa complejidad que no tiene recompensa.

También sobre el tema de los Controladores, creo que la gente en particular tiende a multiplicar los controladores innecesariamente para los subconjuntos de su modelo de datos principal. Supongamos que tiene un controlador de productos y desea almacenar los productos que un usuario determinado está recopilando en una herramienta de comparación. La mayoría de las personas parecen crear un nuevo controlador para esto, pero es perfectamente legítimo colocarlos en una matriz adicional u otro Enumerable dentro de su Controlador de Productos o Controlador de Clientes, o en su modelo de Cliente. Esto mantiene los objetos que dependen de las mismas funciones y propiedades dentro de un alcance más cercano. El objeto de content en cada controlador es, AFAIK, solo otro Enumerable. Tiene algunas referencias implícitas especiales al controlador, pero no es magia. No hay ninguna razón funcional que haya encontrado para no usar otras adicionales también. Funcionan igual de bien con los enlaces, con #each , etc.

De manera similar, a algunas personas les ENCANTA dividir su aplicación en un millón de archivos, anidarlos en la estructura de archivos, etc. Más poder para usted, si eso le ayuda a visualizar la lógica subyacente, y dejarlo claro para el resto de Tu equipo. Para mí, solo me ralentiza en proyectos con solo un equipo de ingeniería de 1-3 personas. Las personas también tienden a reproducir el estilo basado en archivos de otros sistemas MVC con los que están familiarizados (como Rails), donde los archivos son la estructura explícita necesaria para separar las vistas y otros objetos lógicos. Esto se convierte en un artículo de fe y un hábito profundamente arraigado. Pero en Javascript MVC, he encontrado que a menudo no sirve para tal propósito y es estrictamente redundante para el diseño implícito. Tiendo a usar un solo archivo cuidadosamente organizado para toda mi aplicación Ember (separándola de cualquier otro JS que no sea de biblioteca), con mucha sangría y anidación donde eso me ayuda a visualizar la jerarquía. Sea lo que sea lo que haga, en cuanto al archivo, todo es lo mismo en el tiempo de ejecución, siempre que lo entregue en el lugar correcto en el momento adecuado. Con Ember y JS, la estructura de archivos es para las necesidades de su equipo, y nada más. Calibrar en consecuencia.

(CAVEAT IMPORTANTE: si usa un millón de archivos, es mejor que use un precompilador para manifestarlos todos juntos para su entrega al usuario, o va a tener un gran impacto de latencia en la entrega de todos esos archivos por separado .)

(OTRO AVISO IMPORTANTE: con un equipo grande o un programa de lanzamiento diario rápido como el de GitHub , la separación de su lógica basada en archivos puede hacer que el control de versiones sea más fácil que hacer muchas combinaciones en el mismo archivo, donde su herramienta de combinación puede confundirse. , esta es una cuestión de administrar y monitorear sus procesos humanos, y hacer combinaciones cuidadosamente, en lugar de un requisito técnico impuesto por su marco JS.)

(ÚLTIMO CAVEAT IMPORTANTE: de nuevo, a veces, la diferencia entre un requisito técnico y un requisito humano / de procedimiento es confusa. Si rompes el cerebro de tu desarrollador, también tiendes a tener una aplicación defectuosa. Por lo tanto, haz lo que funcione para las personas y los procesos. tienes que lidiar con conseguirlo construido.)

Como dije antes, YMMV. No soy un Dios programador, como se puede ver en mi puntuación de reputación, por lo que puedes sentirte libre de ignorarme. Pero estoy detrás de la idea de que debería usar solo la mayor complejidad, la estructura de archivos y las abstracciones de nivel superior (como el enrutamiento, que en realidad puede ser una exageración para las aplicaciones de una sola página de propósito limitado). tus necesidades; y no mas.

Estoy tratando de entender las mejores prácticas para estructurar una aplicación ember.js. Esta diapositiva de Tomdale:

https://speakerdeck.com/u/tomdale/p/emberjs-more-than-meets-the-eye?slide=55

tiene una descripción concisa de cómo distribuir la lógica de la aplicación. Sin embargo, al intentar seguir estas pautas he encontrado algunos problemas:

  1. El enrutador está creciendo demasiado grande. De acuerdo con la presentación, el enrutador "responde a los eventos desde las vistas", pero esto resulta en una gran cantidad de código cuando hay docenas de vistas.
  2. Hay una gran cantidad de controladores. En una aplicación de Rails, las acciones CRUD normalmente residen en el mismo controlador, sin embargo, para las aplicaciones de brasas parece que debería haber un solo controlador para enumerar los registros, uno para ver un registro, uno para crear un registro, etc.

No se siente muy SECO porque estoy terminando con tantos archivos entre las plantillas de controladores, vistas y manillares, que solo tienen un par de líneas de código.

Estoy tratando de decidir si el problema es que estoy aplicando las pautas incorrectamente o si estas pautas solo funcionan para aplicaciones triviales.

¿Alguien tiene algún consejo, especialmente sobre cómo administrar el crecimiento del enrutador?


Creo que estamos desarrollando una aplicación de brasas bastante grande (aproximadamente 45 vistas en este momento). Implica casi el mismo conteo de controladores y plantillas). De hecho, nuestro enrutador es bastante grande, pero lo gestionamos con bastante facilidad al dividirlo en muchos archivos. Básicamente, cada archivo representa una pantalla de la aplicación y es responsable de mantener un conjunto funcional. Aquí hay un extracto del enrutador:

Router = Ember.Router.extend({ root: Ember.Route.extend({ index: Ember.Route.extend({ route: ''/'', unlogged: Ember.Route.extend({ route: ''welcome'', connectOutlets: function (router) { var applicationController = router.get(''applicationController''); applicationController.connectOutlet(''welcome''); } }), logged: Ember.Route.extend({ route: ''app'', projects: Ember.Route.extend({ route: ''projects'', collection: ProjectsRoute, member: ProjectRoute, showProjects: function (router) { router.transitionTo(''projects.collection''); } }) }) })

Entonces lo mismo en el ProjectRoute . Cada vez que parece que hay muchas características en una ruta, la dividimos. Incluso puede volver a abrir una ruta para ampliarla, y para enchufar otra funcionalidad.

ProjectState.reopen({ scenarios: ScenariosRoute, showScenarios: function (router) { router.transitionTo(''scenarios.collection''); } });

Implica más archivos, pero con una buena organización, no es difícil de mantener, ya que es muy raro que trabaje en todas las funciones al mismo tiempo. Por lo general, no tengo más 4 archivos abiertos simultáneamente (vista, controlador, plantilla, ruta)

No sé si es una buena práctica, pero funciona bastante bien para nosotros