2012-04-20 11 views
21

Tengo una aplicación que en este momento contiene una vista de objetos del mismo modelo. Ellos se recuperan del servidor, en bucle a través y se añaden al controlador de la lista utilizando un método addember.js - cuál es el patrón correcto de controlador/vista para crear un nuevo modelo

<script> 
App.Controllers.List = Em.ArrayProxy.create({ 
    content: Ember.A([]), 
    add: function(obj){ 
    this.pushObject(obj); 
    } 
}); 
</script> 

Ahora estoy trabajando en una parte donde el usuario crea un nuevo objeto que (después de pasar la validación) se añadirá a la lista y también enviado al servidor.

No encuentro ejemplos del mejor patrón para crear un nuevo objeto a través de un formulario de entrada. Puedo ver algunas opciones, y he implementado parcialmente algunas, pero nada se siente bien.

  • crear una vista con elementos de formulario adecuados y un método para instanciar el modelo usando diversas propiedades recuperados de los elementos del formulario utilizando .get()
  • crear un modelo en elementos de contenido y forma se unen de la vista a eso. Incluir un método en la vista para añadir a la matriz de controlador/guardar en el servidor
  • Crear un modelo, añadirlo a la matriz de controlador y abrirlo para la edición de

puedo especie de luchar hasta la funcionalidad I quiero, pero preferiría asegurarme de estar al tanto de las mejores prácticas.

actualmente tienen algo como esto (que es la segunda bala en mi lista)

<script> 
App.Views.ItemCreate = Em.View.extend({ 
    content: App.Models.Item.create({}), 
    templateName: 'create', 
    createButton: function(){ 

    var itemObj = this.get('content'); 
    var item = {}; 
    item.title = this.get('content').get('title'); 

    $.ajax({ 
     type: 'POST', 
     url: '/test/data.json', 
     data: item, 
     dataType: 'json', 
     success: function(responseData, textStatus, jqXHR) { 
     App.Controllers.List.add(itemObj); 
     } 
    }); 
    } 
}); 
</script> 

<script type="text/x-handlebars" data-template-name="create"> 
    {{view Em.TextField id="create-title" valueBinding="content.title"}} 
    <a href="#" {{action "createButton" }}>Create</a> 
</script> 

Cualquier ayuda muy apreciada

NOTAS

He cambiado la respuesta correcta a pangratz's. Aunque las otras respuestas respondieron directamente mi pregunta, creo que aquellos que encuentran esto a través de Google deben referirse a la respuesta proporcionada por Pangratz, ya que no solo es un buen MVC, sino que es más Ember-y:

Respuesta

23

Comunicarse con el servidor es definitivamente algo que no se debe hacer en la vista. Esto es algo para lo que es un controlador. Para separar las diferentes partes de la aplicación, incluso consideraría implementar un DataSource que maneje las solicitudes AJAX. Esta división hace que su aplicación sea más comprobable y que cada componente sea reutilizable. Las conexiones concretas de vista, controlador y fuente de datos se realizan a través de enlaces.

El flujo de trabajo para su caso podría ser el siguiente:

  • La vista muestra el formulario de edición, que' los valores están sujetos a un controlador
  • La vista se ocupa de una acción de guardar el cual le indica al controlador para ahorrar el objeto creado
  • los delegados del controlador del ahorro a la fuente de datos que a continuación se inicia finalmente la petición AJAX
  • el controlador recibe una notificación cuando el objeto se ha guardado

También debe mirar ember-data, que es un almacenamiento de datos del lado del cliente y se encarga de todo el modelo para usted. También echar un vistazo a The architecture of Ember.js apps - data y EmberJS: Good separation of concerns for Models, Stores, Controllers, Views in a rather complex application?


Vista:

App.View.ItemCreate = Ember.View.extend({ 
    templateName: 'create', 
    createObject: function(evt) { 
    var object = this.get('content'); 
    var controller = this.get('controller'); 
    controller.createObject(object); 
    } 
}); 

controlador:

App.Controllers.List = Ember.ArrayProxy.extend({ 
    content: [], 
    createObject: function(hash) { 
    var dataSource = this.get('dataSource'); 
    dataSource.createObject(hash, this, this.createdObject); 
    }, 
    createdObject: function(object) { 
    this.pushObject(object); 
    } 
}); 

DataSource:

App.DataSource = Ember.Object.extend({ 
    createObject: function(hash, target, callback) { 
    Ember.$.ajax({ 
     success: function(data) { 
     callback.apply(target, data); 
     } 
    }); 
    } 
}); 

pegamento todo junto :

App.dataSource = App.DataSource.create(); 
App.listController = App.Controllers.List.create({ 
    dataSourceBinding: 'App.dataSource' 
}); 

App.View.ItemCreate.create({ 
    controllerBinding: 'App.listController' 
}).append(); 
+1

Gracias también por esto. Me di cuenta de que comencé a reescribir un poco de datos de ascuas un poco cuando implementé la fuente de datos, ya lo he usado en un contexto ligeramente diferente y he tenido un comportamiento no agotado, ¡lo intentaré de nuevo! – joevallender

+2

Además, apenas se ha notado para cualquier otra persona que se encuentre con esto: en la fuente de datos función createObject, si se usa apply debería ser callback.apply (target, [data]) o callback.call (target, data) y usted probablemente esté usando un self/_this/que haya pasado a la función ajax en lugar de los datos brutos devueltos – joevallender

2

Si desea siga un modelo estricto de MVC, entonces el modelo nunca se debe crear en la vista, sino en el controlador. Ember todavía es muy joven y aún no tiene ningún patrón definido, lo que yo haría es tener su modelo establecido como el contenido de la vista (como ya lo hizo) con todas las entradas vinculadas a los diferentes atributos del modelo. Luego, cuando se pulsa el botón:

createButton: function(){ 
    App.Controllers.List.create(this.get('content')); 
} 

En el controlador:

create: function(model) { 
    if model.valid() { //validates the model 
    model.save({ 
     onSuccess: function(response) { // callback 
     var item = App.Models.Item.create(response.item) 
     App.controllers.List.add(item) 
     } 
    }) 
    } 

Y finalmente el modelo:

save: function(options) { 
    $.ajax({ 
    type: 'POST', 
    url: '/test/data.json', 
    data: item, 
    dataType: 'json', 
    success: options.onsuccess 
    }); 
} 

Ésta es la manera en que otras js marcos esperan que trabaja. Se siente un poco más detallado y complejo, pero mantiene las cosas en su lugar

+0

Gracias por la respuesta. Antes de que respondiera, terminé agregando un objeto a mi matriz de controladores e invocando su modo de edición mientras lo instanciaba. Funciona en mi caso ya que normalmente todo se edita en su lugar. No lo escribí tan bien (¡y mi POST ajax estuvo en la vista!) Así que lo trabajaré más cerca de tu versión. Muy claro, gracias. – joevallender

Cuestiones relacionadas