guide examples ember blog array javascript ember.js ember-old-router

javascript - examples - Ember.js: ¿dónde debería almacenarse el estado de la interfaz?



ember js wikipedia (1)

¿Existe una historia oficial de dónde debe residir el estado de la interfaz (en oposición al estado del modelo persistente) en una aplicación Ember.js?

En la parte "Respuesta a eventos iniciados por el usuario" de los documentos del enrutador , hay un ejemplo de delegación de eventos de clic en el método "showPhoto" de una foto, pero tener un modelo "show" parece una mezcla indeseable de inquietudes.

Entiendo que en muchos casos el estado debe almacenarse en el enrutador para que el estado de la interfaz se represente en la URL y se restaure si actualiza la página o envía la url a alguien. Pero, ¿qué pasa con el estado no jerárquico, como la lista de elementos seleccionados en una página?

Idealmente, ese tipo de estado se serializaría como parámetros de consulta / hash (por ejemplo: http://www.hipmunk.com/flights/QSF-to-NYC#!dates=Sep15,Sep16p1;kind=flight&locations=QSF,YYZ&dates=Sep15 , Sep23 ~ tab = 1 ) pero hasta donde yo sé, el enrutador no ofrece esa funcionalidad, ¿o sí?

En BackboneConf, Jeremy Ashkenas dijo que la forma correcta de hacerlo en Backbone era simplemente almacenar el estado en el modelo también (tenía un ejemplo de un modelo con un campo "seleccionado"). Pero creo que Tom Dale dijo que no creía que fuera una buena idea, y no cómo debería hacerse en Ember. Lamentablemente, no recuerdo que mencionara cómo debería hacerse.


Si desea que el estado sea enrutable (es decir, accesible a través de una url), entonces debe ser serializable y deserializable a través del enrutador de ember. Si el estado es transitorio y no enrutable, probablemente lo mejor sea mantenerlo en el controlador.

Si necesita representar un estado de interfaz complejo en varios modelos (por ejemplo, para seleccionar elementos en una lista), considere mantener una matriz de objetos específica del controlador que envuelva los modelos de datos subyacentes. Creo que es hackish representar el estado de visualización directamente en los modelos, especialmente si esos modelos se utilizan en múltiples vistas.

Para el ejemplo que proporcionó, podría hacer algo como esto para conectar una ruta compleja:

Ember.Route.extend({ route: "flights/:cities/dates/:dates", serialize: function(router, context){ return {cities: context.get(''cities''), dates: context.get(''dates'')}; }, deserialize: function(router, params){ // return a context object that will be passed into connectOutlets() return {cities: params.cities, dates: params.dates}; }, connectOutlets: function(router, context) { // pass the context from deserialize() in as the content of a FlightController router.get(''applicationController'').connectOutlet(''flight'', context); } })

Tenga en cuenta que también puede utilizar una ruta como "flights? Cities =: cities & dates =: fechas", pero lo anterior es probablemente más limpio y más amigable con el SEO.

Ampliado después de los comentarios de Gabriel: si desea mantener una serie de búsquedas, cada una de las cuales reside en su propia pestaña, le recomendaría mantener los datos para esas búsquedas en una matriz de nivel de aplicación (por ejemplo, App.currentUser.activeSearches). Mi razonamiento es que no desea tener que volver a crear esta información cada vez que un usuario cambie de pestaña. En cambio, el enrutador recuperaría estos datos en deserialize() y luego los pasaría como el contexto para connectOutlets() . La vista y el controlador para representar estos datos se deben reconstruir rápidamente en función de este objeto cuando se cambian las pestañas. Permítanme extender mi ejemplo desde arriba:

Ember.Route.extend({ route: "flights/:cities/dates/:dates", serialize: function(router, context){ return {cities: context.get(''cities''), dates: context.get(''dates'')}; }, deserialize: function(router, params){ // find or create a "Search" object that contains the filters and results, // which will be passed into connectOutlets() return App.currentUser.findOrCreateSearch({cities: params.cities, dates: params.dates}); }, connectOutlets: function(router, context) { // pass the context (a search object) from deserialize() in as the content of a FlightController router.get(''applicationController'').connectOutlet(''flight'', context); } })