web-dev-qa-db-ja.com

ember.js-新しいモデルを作成するための正しいコントローラー/ビューパターンは何ですか

現在、同じモデルのオブジェクトのビューが含まれているアプリがあります。それらはサーバーから取得され、ループされ、addメソッドを使用してリストコントローラーに追加されます。

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

現在、ユーザーが新しいオブジェクトを作成する部分に取り組んでいます。このオブジェクトは、(検証に合格した後)リストに追加され、サーバーにも送信されます。

入力フォームを介して新しいオブジェクトを作成するために従うべき最良のパターンの例を見つけることができません。私はいくつかのオプションを見ることができ、いくつかを半実装しましたが、何も正しく感じられません。

  • 適切なフォーム要素と、.get()を使用してフォーム要素から取得したさまざまなプロパティを使用してモデルをインスタンス化するためのメソッドを使用してビューを作成します。
  • ビューのコンテンツにモデルを作成し、フォーム要素をそれにバインドします。コントローラー配列に追加/サーバーに保存するためのメソッドをビューに含めます
  • モデルを作成し、コントローラーアレイに追加して、編集用に開きます

必要な機能と戦うことはできますが、ベストプラクティスを認識していることを確認したいと思います。

私は現在このようなものを持っています(これは私のリストの2番目の箇条書きです)

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

どんな助けでも大歓迎

[〜#〜] notes [〜#〜]

正解をパングラッツに変更しました。他の回答は私の質問に直接答えましたが、Google経由でこれを見つけた人は、それが優れたMVCであるだけでなく、より燃えさしであるため、Pangratzが提供した回答を参照する必要があると思います:o)

21
joevallender

サーバーとの通信は、ビューで実行すべきではないことは間違いありません。これはコントローラーの目的です。アプリケーションのさまざまな部分をさらに分離するために、AJAXリクエストを処理するDataSourceを実装することも検討します。この分割により、アプリケーションがよりテスト可能になり、各コンポーネントが再利用可能になります。次に、ビュー、コントローラー、およびデータソースの具体的な接続がバインディングを介して実現されます。

ケースのワークフローは次のようになります。

  • ビューには編集フォームが表示され、その値はコントローラーにバインドされます
  • ビューは、作成されたオブジェクトを保存するようにコントローラーに指示する保存アクションを処理します
  • コントローラは保存をデータソースに委任し、データソースは最終的にAJAXリクエストを開始します
  • オブジェクトが保存されると、コントローラーに通知されます

また、クライアント側のデータストレージであり、すべての定型文を処理する ember-data も確認する必要があります。 Ember.jsアプリのアーキテクチャ-データ および EmberJS:かなり複雑なアプリケーションでのモデル、ストア、コントローラー、ビューの関心の分離? もご覧ください。


見る:

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

コントローラ:

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

情報元:

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

すべてを接着します:

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

App.View.ItemCreate.create({
  controllerBinding: 'App.listController'
}).append();
23
pangratz

厳密なMVCモデルに従う場合は、モデルをビューではなくコントローラーで作成する必要があります。 Emberはまだ非常に若く、まだ定義されたパターンがありません。私が行うことは、すべての入力がバインドされたビューのコンテンツとしてモデルを設定することです(すでに行ったように)さまざまなモデル属性に移動します。ボタンを押すと、次のようになります。

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

コントローラ上:

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

そして最後にモデル:

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

これは、他のjsフレームワークが期待する方法です。もう少し冗長で複雑に感じますが、物事を適切に保ちます