2012-04-20 9 views
21

Ho un'app che al momento contiene una vista di oggetti dello stesso modello. Essi vengono recuperati dal server, collegato attraverso e aggiunti al controller elenco utilizzando un metodo addember.js - qual è il modello di controllo/visualizzazione corretto per la creazione di un nuovo modello

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

Ora sto lavorando su una parte in cui l'utente crea un nuovo oggetto che (dopo aver superato la convalida) sarà aggiunto l'elenco e anche inviato al server.

Non riesco a trovare alcun esempio sui migliori schemi da seguire per creare un nuovo oggetto tramite un modulo di input. Riesco a vedere alcune opzioni e ne ho parzialmente implementate alcune, ma non mi sembra giusto.

  • creare una vista con opportuni elementi di modulo e un metodo per istanziare il modello utilizzando varie proprietà recuperate dagli elementi modulo utilizzando .get()
  • creare un modello di contenuto e forma legano elementi della vista di questo. Includere un metodo sulla vista per l'aggiunta alla matrice di controllo/salvataggio al server
  • Creare un modello, aggiungerlo alla array controller e aprirlo per la modifica

posso tipo di lotta la funzionalità I voglio, ma preferirei assicurarmi di essere a conoscenza delle migliori pratiche.

Al momento ho qualcosa di simile (che è il secondo punto sulla mia 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> 

Qualsiasi aiuto molto apprezzato

NOTE

ho cambiato la risposta corretta a Pangratz di. Sebbene le altre risposte rispondessero direttamente alla mia domanda, credo che chi trova questo tramite Google dovrebbe fare riferimento alla risposta Pangratz fornita non solo è buona MVC, ma è più Ember-y: o)

risposta

23

Comunicare con il server è sicuramente qualcosa che non dovrebbe essere fatto nella vista. Questo è qualcosa per cui è un controller. Per separare ulteriormente le diverse parti dell'applicazione, prenderei in considerazione l'implementazione di un DataSource che gestisce le richieste AJAX. Questa suddivisione rende l'applicazione più testabile e ogni componente riutilizzabile. I collegamenti concreti della vista, del controller e della sorgente dati vengono quindi realizzati tramite binding.

Il flusso di lavoro per il vostro caso potrebbe essere la seguente:

  • La visualizzazione mostra il vostro modulo di modifica, che' i valori sono destinati a un controller
  • La vista gestisce Salvataggio azione che racconta il controller per salvare l'oggetto creato
  • I delegati controllore risparmio all'origine dati che poi inizia finalmente la richiesta AJAX
  • il controllore è notificato quando l'oggetto è stato salvato

Si dovrebbe anche guardare ember-data che è una memoria di dati lato client e gestisce tutto il boilerplate per voi. Anche dare un'occhiata a The architecture of Ember.js apps - data e 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); 
    } 
}); 

Controller:

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); 
     } 
    }); 
    } 
}); 

Colla tutto insieme :

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

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

Grazie anche a questo. Ho notato che ho iniziato a riscrivere i dati di ember un po 'quando ho implementato la sorgente di dati, l'ho già usato in un contesto leggermente diverso e ho avuto un comportamento non corretto, lo farò un altro tentativo, penso! – joevallender

+2

Inoltre, appena notato per chiunque altro si imbatta in questo: nella funzione di creazione di dati source source, se viene applicato si dovrebbe essere callback.apply (destinazione, [dati]) o callback.call (destinazione, dati) e si probabilmente stai usando un self/_questo/che hai passato nella funzione ajax invece dei dati grezzi restituiti – joevallender

2

Se si desidera seguire un modello MVC rigoroso, quindi il modello non dovrebbe mai essere creato sulla vista ma sul controller. Ember è ancora molto giovane e non ha ancora definito alcun pattern, quello che vorrei fare è avere il tuo modello impostato come il contenuto della vista (come hai già fatto) con tutti gli input legati ai diversi attributi del modello. Poi, quando si preme il tasto:

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

Sul controller:

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) 
     } 
    }) 
    } 

E infine il modello:

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

Questo è il modo in cui gli altri JS quadri si aspettano di lavorare. Sembra un po 'più prolisso e complesso, ma mantiene le cose in ordine

+0

Grazie per la risposta. Prima che tu rispondessi, ho finito per aggiungere un oggetto al mio array di controller e richiamare il suo editMode mentre lo istanziavo. Funziona nel mio caso poiché tutto sarebbe normalmente modificato sul posto. Non avevo scritto abbastanza bene come quello (e il mio POST ajax era nella vista!) Quindi lavorerò più vicino alla tua versione. Molto chiaro, grazie. – joevallender

Problemi correlati