2010-06-14 21 views
6

tl; dr: ¿Cómo se implementa MVC en JavaScript de forma limpia?Modelo-Vista-Controlador en JavaScript

Estoy tratando de implementar MVC en JavaScript. He buscado en Google y reorganizado con mi código innumerables veces, pero no he encontrado una solución adecuada. (El código simplemente "no se siente bien").

Así es como lo estoy haciendo ahora mismo. Es increíblemente complicado y es un dolor trabajar con él (pero aún mejor que el montón de código que tenía antes). Tiene soluciones feos que derrotan el propósito de MVC.

Y he aquí, el desorden, si eres muy valiente:

// Create a "main model" 
var main = Model0(); 

function Model0() { 
    // Create an associated view and store its methods in "view" 
    var view = View0(); 

    // Create a submodel and pass it a function 
    // that will "subviewify" the submodel's view 
    var model1 = Model1(function (subview) { 
     view.subviewify(subview); 
    }); 

    // Return model methods that can be used by 
    // the controller (the onchange handlers) 
    return { 
     'updateModel1': function (newValue) { 
      model1.update(newValue); 
     } 
    }; 
} 

function Model1(makeSubView) { 
    var info = ''; 

    // Make an associated view and attach the view 
    // to the parent view using the passed function 
    var view = View1(); 
    makeSubView(view.__view); // Dirty dirty 

    // Return model methods that can be used by 
    // the parent model (and so the controller) 
    return { 
     'update': function (newValue) { 
      info = newValue; 

      // Notify the view of the new information 
      view.events.value(info); 
     } 
    }; 
} 

function View0() { 
    var thing = document.getElementById('theDiv'); 
    var input = document.getElementById('theInput'); 

    // This is the "controller", bear with me 
    input.onchange = function() { 
     // Ugly, uses a global to contact the model 
     main.updateModel1(this.value); 
    }; 

    return { 
     'events': {}, 

     // Adds a subview to this view. 
     'subviewify': function (subview) { 
      thing.appendChild(subview); 
     } 
    }; 
} 

// This is a subview. 
function View1() { 

    var element = document.createElement('div'); 
    return { 
     'events': { 
      // When the value changes this is 
      // called so the view can be updated 
      'value': function (newValue) { 
       element.innerHTML = newValue; 
      } 
     }, 

     // ..Expose the DOM representation of the subview 
     // so it can be attached to a parent view 
     '__view': element 
    }; 
} 

¿Cómo se puede implementar MVC en JavaScript de una manera más limpia? ¿Cómo puedo mejorar este sistema? ¿O es este el camino completamente equivocado, debería seguir otro patrón?

+0

(cuatro años después) Utilice AngularJS. –

+1

Si solo intentabas entender cómo funciona MVC en Javascript, entonces preguntar cómo implementarlo es perfectamente razonable. Demasiados desarrolladores utilizan marcos ahora sin entender realmente cómo funcionan. – NobodyReally

Respuesta

0

Para ser sincero, MVC no es adecuado para Javascript. Puede respaldar los fundamentos básicos del diseño, seguro: puede crear pseudoclases para que actúen como controladores o modelos, admitir herencia básica, y puede hacer que manipule o cree cualquier cantidad de elementos DOM, pero hay un precio que paga por eso - en gastos generales, accesibilidad y usabilidad.

En mi opinión, considero que Javascript es más un aumento: la mentalidad de KISS existe por una buena razón. Si está interesado en mejores formas de organizar su código, siempre existe la opción de empaquetar la funcionalidad relacionada en módulos (sic) y abstraer porciones según corresponda. Por ejemplo, crear una fábrica para hacer una gestión de solicitudes AJAX más compleja, o una pseudoclass para manejar el procesamiento de tipos de datos similares. El uso de una función base estándar para controladores, otro para modelos, etc., como prototipos para nuevas instancias de esos objetos puede lograr una funcionalidad similar ... pero, una vez más, está yendo contra corriente.

Sin embargo, si estás atascado en la idea MVC sólo por el bien de la estructura, considere algo como lo siguiente:

;(function(window, $) { 
    /** 
    * Event Object 
    * A quick description goes here. 
    **/ 
    var Events = window.Events = { 
     'bindTrackables': function() { 
      $('a.trackable').live('click', function() { 
       if(!_gaq) 
        _gaq = []; 
       _gaq.push(['_trackPageview', '/ajax/foobar']); 
      }); 
     }, 
     'bindSomeEvent': function() { 
      // etc 
     } 
    }; 

    /** 
    * Data Cache 
    * I'll need to remember stuff later, so I store it here 
    **/ 
    var Cache = window.Cache = { 
     'data': {}, 
     'store': function(key, value) { 
      Cache.data[key] = value; 
     }, 
     'fetch': function(key) { 
      return Cache.data[key]; 
     } 
    }; 

    /** 
    * Request Object 
    * Stores native AJAX requests for later use 
    **/ 
    var Request = window.Request = { 
     'current_requests': [], 
     'send': function(url, type, data, callback) { 
      Request.current_requests.push($.ajax({ 
       'url': url, 
       'type': type, 
       'data': data, 
       'callback': callback 
      })); 
     }, 
    } 

    // add some private logic here 
})(window, jQuery); 

Es muy básico, pero se entiende la idea. El código modular es la clave ... en JS, esto es más importante que forzar a su aplicación (o el lenguaje) para que se ajuste a un estilo determinado.

+1

Estoy totalmente de acuerdo con su punto, pero mi aplicación es complicada (es una aplicación Gmail-esque, no tan grande, pero el punto sigue siendo). Incluso organizado de manera similar al modelo en su publicación, el código era un desastre; Tenía que encontrar un modelo de organización para no volverme loco. No necesito adherirme a MVC si es una tarea complicada de implementar (bien), pero en ese caso sí necesito un patrón de reemplazo. –

6

Existen al menos un par de marcos MVC establecidos y utilizables para JavaScript JavaScriptMVC y pureMVC. Probablemente hay más. He usado JavaScriptMVC para aplicaciones basadas en navegador y Air, y sigo volviendo a él, tiene sus problemas pero he encontrado que es bastante útil.
También hay otras soluciones, eche un vistazo a Sammy, algo nuevo de lo que he escuchado cosas buenas. No me he utilizado, pero tengo la intención de intentar pronto. No sé lo suficiente para describirlo correctamente, pero para mí parece un controlador frontal que funciona en rutas, un sistema de plantillas y almacenes de datos ReSTful. No estoy seguro si es MVC pero tiene ingredientes similares.

Tengo que estar en desacuerdo con mway's answer. MVC puede ser un poco diferente para implementar en JavaScript, pero sus beneficios son muy importantes para organising this mess. Los patrones de diseño generalmente asociados con los lenguajes OO no salen por la ventana solo porque js no se basa en clases.

Diría que MVC es más adecuado para aplicaciones de JavaScript que para aplicaciones basadas en solicitudes (del lado del servidor).Esos objetos pueden permanecer por un tiempo en una aplicación de JavaScript de una página, minutos si no horas, y tener una forma bien organizada de organizar su interacción hará que su código sea mucho más robusto y fácil de manejar. There are books on the subject.

Un par de otros puntos con respecto al código que ha publicado.

  • Los objetos view tienen la responsabilidad de aplicar detectores de eventos a los elementos DOM. Este es el trabajo del controlador. La vista solo representa el HTML: el controlador escucha los eventos y actúa en consecuencia.
  • Sus modelos parecen conocer sus puntos de vista. La capa del modelo debe tener un conocimiento mínimo de la capa de vista (quizás esté registrado como observers). Mantenga su modelo limpio y al grano, me refiero al punto de negocios: lógica de negocios. En las aplicaciones de js, es posible que esté realizando un proxy para una capa de modelo de lado de corte, pero es importante para su cordura mantener el modelo en la lógica comercial y nada más. La lógica de la aplicación es el trabajo de los controladores