support sheet es6 ecmascript cheat javascript dependency-injection passive-view

sheet - ¿Cuál es la forma correcta de conectar 2 objetos javascript?



javascript cheat sheet pdf (6)

Actualmente me estoy enfrentando a un enigma: ¿Cuál es la forma correcta de conectar 2 objetos javascript?

Imagina una aplicación como un editor de texto con varios archivos diferentes. Tengo alguna página HTML que representa la vista para el cuaderno. Tengo un archivo notebook.js que contiene definiciones de clase para NotebookController y Notebook View.

NotebookControler objeto responsable de realizar la lógica empresarial en el Notebook como "Guardar Notebook", "Cargar Notebook", "Nuevo Notebook". NotebookView es responsable de administrar el HTML que se utiliza para la presentación. Hace cosas de bajo nivel como "obtener / configurar el cuerpo del notebook" "obtener / configurar el nombre del notebook". También escucha eventos DOM (onClick) y dispara eventos empresariales (saveNotebook). Este es mi intento en el patrón de vista pasiva.

Quiero que mi código del lado del cliente de javascript esté orientado a objetos, tenga problemas separados y pueda probarse por unidad. Quiero probar NotebookController con un simulador de NotebookView y viceversa. Esto significa que no puedo crear una instancia de NotebookView dentro del NotebookController. Yo también

  • Ponga un poco de lógica en mi notebook.js que conecta los 2
  • Tengo una función global en mi aplicación que sabe crear una instancia de cada una y conectarlas
  • Use la inyección de dependencia, ya sea de cosecha propia o algo así como SquirrelIoc

En Java, la elección es natural: usar Spring. Pero eso no parece muy JavaScript-y. ¿Qué es lo correcto a hacer?


Gracias por la perspicacia. Terminé escribiendo una utilidad de inyección de dependencia de JavaScript simple. Después de debatir por un tiempo y sus comentarios, me di cuenta de que DI era realmente la respuesta correcta porque:

  1. Separó totalmente las preocupaciones de cableado de la lógica de negocios mientras mantenía la lógica de cableado cerca de las cosas que se estaban conectando.
  2. Me permitió proporcionar genéricamente una devolución de llamada de "todos ustedes están cableados" en mis objetos para poder realizar una inicialización de 3 fases: crear una instancia de todo, cablear todo, llamar a las devoluciones de llamada de todos y decirles que están cableados.
  3. Fue fácil comprobar la falta de problemas de dependencia.

Así que aquí está la utilidad DI:

var Dependency = function(_name, _instance, _dependencyMap) { this.name = _name; this.instance = _instance; this.dependencyMap = _dependencyMap; } Dependency.prototype.toString = function() { return this.name; } CONCORD.dependencyinjection = {}; CONCORD.dependencyinjection.Context = function() { this.registry = {}; } CONCORD.dependencyinjection.Context.prototype = { register : function(name, instance, dependencyMap) { this.registry[name] = new Dependency(name, instance, dependencyMap); }, get : function(name) { var dependency = this.registry[name]; return dependency != null ? dependency.instance : null; }, init : function() { YAHOO.log("Initializing Dependency Injection","info","CONCORD.dependencyinjection.Context"); var registryKey; var dependencyKey; var dependency; var afterDependenciesSet = []; for (registryKey in this.registry) { dependency = this.registry[registryKey]; YAHOO.log("Initializing " + dependency.name,"debug","CONCORD.dependencyinjection.Context"); for(dependencyKey in dependency.dependencyMap) { var name = dependency.dependencyMap[dependencyKey]; var instance = this.get(name); if(instance == null) { throw "Unsatisfied Dependency: "+dependency+"."+dependencyKey+" could not find instance for "+name; } dependency.instance[dependencyKey] = instance; } if(typeof dependency.instance[''afterDependenciesSet''] != ''undefined'') { afterDependenciesSet.push(dependency); } } var i; for(i = 0; i < afterDependenciesSet.length; i++) { afterDependenciesSet[i].instance.afterDependenciesSet(); } } }


Intentaré probar esto, pero será un poco difícil sin ver ningún código real. Personalmente, nunca he visto a nadie hacer un intento tan específico en (M) VC con JavaScript o IoC.

En primer lugar, ¿con qué vas a probar? Si aún no lo has hecho, revisa el video YUI Test, que contiene buena información sobre las pruebas unitarias con javascript.

En segundo lugar, cuando dices "la mejor manera de conectar esa agregación" probablemente lo haría como configurador con el controlador

// Production var cont = new NotebookController(); cont.setView( new NotebookView() ); // Testing the View var cont = new NotebookController(); cont.setView( new MockNotebookView() ); // Testing the Controller var cont = new MockNotebookController(); cont.setView( new NotebookView() ); // Testing both var cont = new MockNotebookController(); cont.setView( new MockNotebookView() );

Pero esto hace una gran suposición sobre cómo ha diseñado su controlador y ver los objetos ya.


Inyección de dependencia es probablemente su mejor apuesta. En comparación con Java, algunos aspectos de esto son más fáciles de hacer en el código JS, ya que puede pasar un objeto lleno de devoluciones de llamada a su NotebookController. Otros aspectos son más difíciles, porque no tiene el análisis de código estático para formalizar la interfaz entre ellos.



Tengo una inversión de la biblioteca de control para JavaScript, estoy muy contento con él. https://github.com/fschwiet/jsfioc . También es compatible con eventos, así que si quieres tener un evento de inicio está bien. Podría usar más documentación ...

http://github.com/fschwiet/jsfioc

Otra opción (¿más reciente?), Que tiene mejor documentación y asistencia, es requireJS (http://requirejs.org/).


Yo diría, sólo cablearlos juntos:

function wireTogether() { var v = new View(); var c = new Controller(); c.setView(v); }

Pero, por supuesto, surge otra pregunta: ¿cómo se prueba la función wireTogether ()?

Afortunadamente, JavaScript es un lenguaje muy dinámico, por lo que puede asignar nuevos valores a Vista y Controlador:

var ok = false; View.prototype.isOurMock = true; Controller.prototype.setView = function(v) { ok = v.isOurMock; } wireTogether(); alert( ok ? "Test passed" : "Test failed" );