para hashtags fotografia arquitectura architecture knockout.js

architecture - hashtags para fotografia de arquitectura



¿KnockoutJS proporciona una arquitectura adecuada para la construcción de grandes aplicaciones web? (4)

Pregunta rápida:

¿KnockoutJS proporcionará una base sólida para desarrollar una gran aplicación web? Tengo miedo de tener una gran vista. Modelo que se volverá inmanejable.

Información de fondo

Construiré una aplicación web que estará fuertemente basada en el cliente. El backend será un punto final RESTful. Toda la interfaz de la aplicación web se compilará en HTML / CSS / JS puro, sin necesidad de secuencias de comandos del lado del servidor.

La aplicación web en sí consistirá en varias aplicaciones más pequeñas con un inicio de sesión general (algo así como las aplicaciones web de Google donde tiene Gmail, Documentos, Calendario, Lector, etc.).

Cada una de esas aplicaciones web tendrá algunas funciones comunes (como una vista de árbol de la barra lateral, una vista del menú de la barra superior, un sistema de notificaciones) y algunas características exclusivas de la aplicación. Normalmente rompo mis aplicaciones para encapsular la funcionalidad, algo así como:

var myNamespace = { common: { settings: {}, user: {}, notifications: {} }, app1: {}, app2: {}, app3: {} };

Ahora, realmente disfruto trabajar con KnockoutJS y pensé que sería útil para construir algunos elementos de mi proyecto (como el sistema de notificación o una vista de cuadrícula avanzada con actualización automática, ya que la aplicación admitirá la colaboración). Pero simplemente no puedo imaginar dónde poner mi modelo de vista en esta estructura.

Solo puedo encontrar ejemplos triviales de cómo crear aplicaciones con KnockoutJS. ¿Puedes construir algo más avanzado que un lector de Twitter con él? ¿Hay algún buen ejemplo de cómo desglosar una gran cantidad de funcionalidades en viewModel, o quizás en muchos viewModels?

Solución propuesta

Si bien la pregunta más teórica (la pregunta rápida) todavía está sin respuesta aquí, creo que encontré una solución que funciona en la práctica. La respuesta de @Simon me dio algo de reflexión, y esto es lo que tengo hasta ahora:

// First: a collection of Observables that I want to share ld.collectionOfObservables = { notifications: ko.observableArray([]), }; // Now let''s define a viewModel. I put all my stuff inside the // ''ld'' namespace to avoid cluttering the global object. ld.viewModel1 = function (args) { // Look inside args and bind all given parameters // Normally you will want args to be an object of Observables. for (var key in args) { if (args.hasOwnProperty(key)) { this[key] = args[key]; } }; // So, by now we already have some observables in // ''this'', if there were any supplied in ''args''. // Additionally, we define some model-unique properties/observables this.folders = [ ''Inbox'', ''Archive'', ''Sent'', ''Spam'' ]; this.selectedFolder = ko.observable(''Inbox''); }; // *** Let''s pretend I create similar class and call it ld.viewModel2 *** ld.viewModel2 = function (args) { .... } // OK, now go on and instantiate our viewModels! // This is the fun part: we can provide 0-many observables here, by providing them in an object // This way we can share observables among viewModels by simply suppling the same observables to different viewModels var vm1 = new ld.viewModel1({ notifications: ld.collectionOfObservables.notifications, // we take an Observable that was defined in the collection }); var vm2 = new ld.viewModel2({ notifications: ld.collectionOfObservables.notifications, // shared with vm1 }); // Of course, we could just send the entire ld.collectionOfObservables as an array // but I wanted to show that you can be more flexible and chose what to share. // Not easy to illustrate with *one* shared Observable - notifications - // but I hope you get the point. :) // Finally, initiate the new viewModels in a specified scope ko.applyBindings(vm1, document.getElementById(''leftPane'')); ko.applyBindings(vm2, document.getElementById(''bottomPane''));

Ahora, si JS tuviera herencia real sería aún mejor porque ahora siento que todos mis modelos de vista comienzan con esto:

for (var key in args) { if (args.hasOwnProperty(key)) { this[key] = args[key]; } };

Pero eso es solo un inconveniente menor. ¡Déjame saber lo que piensas!

Edición 1: ¿Podría ser la solución tan simple como usar el with: binding? Consulte " 1. Control de enlaces de flujo " para ver un ejemplo.

Editar 2: creo que mi última edición fue demasiado rápida. with: enlace puede ayudar con la estructura de su código, pero AFAIK no lo ayuda a compartir observables entre esas partes diferentes. Entonces, la solución propuesta arriba todavía es el camino a seguir.


En mi opinión, podríamos usar KO y compartir modelos de visualización para el alcance del módulo funcional (digamos que el widget funcional tiene múltiples controles html). Podríamos analizar el uso del bus TIBCO Page (Pub / Sub) para la comunicación entre estos módulos funcionales en la página para mantener los módulos funcionales en una página desacoplada y manejable.


Esta es una publicación anterior, pero recientemente construí un framework para exactamente el mismo propósito en este repositorio que llamo gcc-knockout . Todo es un componente e incluso hay un administrador de vistas para cambiar las vistas por completo y mantener el historial al mismo tiempo. Todavía no lo he documentado adecuadamente, pero el repositorio viene con un ejemplo que demuestra algunas de sus características.

Tenga en cuenta que también utilicé Google Closure Compiler. Puede usarlo de forma segura en el modo avanzado dado que exporta adecuadamente las propiedades que usará en las plantillas html. Los componentes se comunican usando goog.events y todo está bastante limpio en este momento. No he usado la utilidad de suscripción de knockout. ¡Siéntete libre de echarle un vistazo y contribuir! Ocasionalmente lo actualizo.


He usado vistas parciales (en Nancy en lugar de MVC), cada una con su propia tarea, cada una con su propio modelo de vista. Creo que funciona maravillosamente: una página complicada dividida en muchos parciales independientes. La mayoría de las vistas parciales tienen su propio módulo / controlador / punto final, por lo que los módulos también son "delgados".

Es una pena que las plantillas de jQuery se descarten, pero ese es un problema diferente.

Lo siento, acabo de volver a leer tu publicación: no hay nada del lado del servidor, ¿entonces no hay manera de dividir la página? Ay. Todavía creo que muchos modelos de vista es el camino a seguir.


Puede usar vistas parciales y compartir observables entre ellas.

var some_observable = ko.observable() var Model1 = function(something) { this.something_1 = something; }; var Model2 = function(something) { this.something_2 = something; }; var view_1 = Model1(some_observable); var view_2 = Model2(some_observable); ko.applyBindings(view_1, document.getElementById(''some-id'')); ko.applyBindings(view_2, document.getElementById(''some-other-id'')); <div id=''some-id''> <input data-bind=''value: something_1'' /> </div> <div id=''some-other-id''> <input data-bind=''value: something_2'' /> </div>

He estado usando este enfoque para mantener una lista de fotos en una aplicación de galería, donde una vista hace miniaturas y otra vista se ocupa de las cargas.