2012-04-20 14 views
21

Mam aplikację, która w tej chwili zawiera widok obiektów tego samego modelu. Są one pobierane z serwera, przelotowe i dodawane do kontrolera liście stosując metodę dodawaniaember.js - jaki jest poprawny kontroler/wzorzec widoku do tworzenia nowego modelu?

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

Teraz pracuję w części, w której użytkownik tworzy nowy obiekt, który (po przejściu walidacji) zostanie dodany do listę, a także wysłane na serwer.

Nie mogę znaleźć przykładów najlepszego wzoru do wykonania w celu utworzenia nowego obiektu za pomocą formularza wejściowego. Widzę kilka opcji i częściowo wdrożyłem kilka, ale nic nie jest w porządku.

  • Tworzenie widoku z odpowiednich elementów formy oraz sposobu uruchamianiu modelu z wykorzystaniem różnych właściwości uzyskane z elementów formy za pomocą .get()
  • Tworzenie modelu w zawartość oraz format wiążą elementów w Widoku z tym. Obejmują metodę na widoku za dodanie do tablicy kontrolera/zapisywania na serwerze
  • Tworzenie modelu, dodaj je do tablicy kontrolera i otwórz go do edycji

mogę rodzaj walki z funkcjonalnością I chcę, ale wolałbym mieć pewność, że mam najlepszą praktykę.

Obecnie mam coś takiego (który jest drugi pocisk na mojej liście)

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

Każda pomoc mile widziana

UWAGI

Zmieniłem poprawną odpowiedź pangratz's. Chociaż inne odpowiedzi bezpośrednio odpowiedziały na moje pytanie, wierzę, że ci, którzy znaleźli to za pośrednictwem Google, powinni odnieść się do odpowiedzi, którą Pangratz podał jako nie tylko dobry MVC, ale jest bardziej Ember-y: o)

Odpowiedz

23

Komunikacja z serwerem to zdecydowanie coś, czego nie powinno się robić w widoku. To jest coś, do czego służy kontroler. Aby dodatkowo oddzielić poszczególne części aplikacji, rozważałbym nawet implementację DataSource, która obsługuje żądania AJAX. Podział ten sprawia, że ​​twoja aplikacja jest bardziej testowalna, a poszczególne składniki można ponownie wykorzystać. Konkretne połączenia widoku, kontrolera i źródła danych są następnie realizowane za pomocą wiązań.

Workflow w Twoim przypadku może być następująca:

  • Widok pokazuje formularz edycji, która”wartości są związane z kontrolerem
  • Widok obsługuje strzał działania, które mówi kontroler, aby zapisać utworzony obiekt
  • delegaci kontroler oszczędność do źródła danych, które następnie wreszcie uruchamia żądania AJAX
  • kontroler jest powiadamiany, gdy obiekt został zapisany

Powinieneś także spojrzeć na ember-data, który jest przechowywany po stronie klienta i obsługuje dla ciebie wszystkie bloki. Również spojrzeć na The architecture of Ember.js apps - data i EmberJS: Good separation of concerns for Models, Stores, Controllers, Views in a rather complex application?


Widok:

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

Kontroler:

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

Klej wszystko razem :

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

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

Dzięki za to. Zauważyłem, że zacząłem przepisywanie danych ember trochę podczas implementacji źródła danych, już używałem tego w nieco innym kontekście i miałem pewne nietypowe zachowanie, postaram się jeszcze raz pomyśleć! – joevallender

+2

Ponadto, został zauważony dla każdego, kto się na to natknął: w źródle danych funkcja createObject, jeśli stosuje się apply, powinna to być callback.apply (target, [data]) lub callback.call (target, data) i Ty prawdopodobnie używał self/_this /, który przeszedłeś do funkcji ajax zamiast zwracanych danych pierwotnych – joevallender

2

Jeśli chcesz postępuj zgodnie ze ścisłym modelem MVC, a model nie powinien być nigdy tworzony w widoku, ale na kontrolerze. Ember jest wciąż bardzo młody i nadal nie ma żadnych zdefiniowanych wzorców, a ja chciałbym, aby twój model był ustawiony jako zawartość widoku (tak jak to już zrobiliście), a wszystkie wejścia wiążą się z różnymi atrybutami modelu. Wtedy, gdy przycisk jest wciśnięty:

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

Na kontrolerze:

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

I wreszcie model:

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

Jest to inny sposób js ram oczekiwać, aby pracować. Czuje się trochę bardziej gadatliwy i skomplikowany, ale utrzymuje rzeczy na swoim miejscu.

+0

Dzięki za odpowiedź. Zanim odpowiedziałeś, w końcu dodałem obiekt do mojej tablicy kontrolerów i wywołałem jego editMode podczas tworzenia instancji. Działa w moim przypadku, ponieważ wszystko będzie normalnie edytowane na miejscu. Nie napisałem tego tak dobrze (a mój widok ajax POST był w widoku!), Więc będę pracował bliżej twojej wersji. Bardzo jasne, dzięki. – joevallender

Powiązane problemy