10

EmberJSv1.0.preでアプリを書いています。私はArrayControllerすべての人のリストを含むを持っています。人、ペット、および各ペットのメモを示すネストされたビューがたくさんあります。

|----------------------------------------|
| John                                   | <- Person
|----------------------------------------|
|   Quincy (Dog)                         | <- Pet
|     - Super ornery                     | <- Note
|     - Likes XYZ Dog food               |
|     - Will eat your socks              |
|                                        |
|   Tom (Cat)                            |
|    - Always (not) catching mice        |
|                                        |
|----------------------------------------|
| Roger                                  |
|----------------------------------------|
|   V (Dog)                              |
|    - Likes XYZ Dog food                |
|    - Sneezes, but it's ok              |
|                                        |
|----------------------------------------|
| ...                                    |

純粋なMVCの観点からは、各子にコントローラーが必要であるように感じますが、Emberでそれを実現する方法がわかりません。一番上のアレイコントローラーがあり、次にすべての個別のビューがあります。メモを削除したり編集したりする場合は、ビューのコンテキストをコントローラーに渡す必要があるようです。

// in the view
click: function () {
  this.get('controller').updateNote(this.get('content'))
}

これは私にとって本当に悪いことだと感じます。ビューはデータの信頼できるソースではないはずです。私の仮定は、ArrayControllerが。itemControlerClassとともにインスタンス化することですitemViewClass

更新:問題をよりよく説明するためにフィドルを作成しました。機能は意図的に不完全です。目的は、リストの項目がクリックされたときにコンテンツを増やして機能を終了することです。

更新:申し訳ありませんが、事故でフィドルを削除しました!私は最終的な解決策に取り組んでいるので、解決策を使って新しいフィドルを作成しようと思います。

4

4 に答える 4

12

「純粋なMVCの観点からは、各子にコントローラーが必要なように感じます」

アイテムごとにコントローラーは必要ありませんが、代わりにオブジェクトのコレクション(People、Pets、Notes)ごとにArrayControllerが必要です。ちなみに、子オブジェクト(犬、メモ)に対するアクションはに渡さないでくださいApp.PersonsController。それは関心の分離の原則を破るでしょう。

Ember.Routerのドキュメントでは、ビューを単一のオブジェクト(例/:people_id)にネストする場合について説明しています。ただし、オブジェクトの配列のビューをネストする必要があります。ビューをネストする方法は考えられません{{outlet}}が、次のようにすることができます。

オブジェクトPeople、Pets、Notesを3つのArrayControllerにロードし、子オブジェクトに対するアクションを対応するArrayControllerに委任します。

App.Router = Ember.Router.extend({
  root: Ember.Route.extend({
    route: '/',
    persons: Ember.Route.extend({
        connectOutlets: function(router) {

          router.get('applicationController').connectOutlet('persons');
          // App.Note.find() fetches all Notes,
          // If you are not using ember-data, make sure the notes are loaded into notesController
          router.set('notesController.content', App.Note.find());
          router.set('petsController.content', App.Pet.find());
        }
    })
  })
});

そして、peopleテンプレートは次のようになり ます。

{{#each person in people}}
  <h1>My name is {{person.name}}</h1>

  {{#each pet in person.pets}}
     I have a pet with name {{pet.name}}
     <a {{action delete pet target="App.router.petsController">Delete pet</a>
  {{/each}}      

  {{view Ember.TextField valueBinding="myNewPetName" type="text"}}
  <a {{action create myNewPetName person target="controller"}}>
    Add a new pet for this person
  </a>


  {{#each note in person.notes}}
    <!-- delete, create, edit ... -->
  {{/each}}

ご覧のとおり、子オブジェクトに対するアクションはそのコントローラー(pet-> petsController)に委任され、オブジェクトをコンテキストとして渡します。アクションの場合create、コントローラーはペットが誰にいるのかを知る必要がありますbelongsTo。したがって、2つのコンテキストを渡します。人とペットのプロパティです(簡単にするために、ペットの名前だけを想定しました)。

App.petsControllersには、次の行に沿ったアクションが必要です。

App.PetsController = Ember.ArrayController.extend({
   delete: function(e) {
     var context = e.context;
     this.get('content').removeObject(context);
     // Also, if you use ember-data,
     // App.Pet.deleteRecord(context);
   },

   create: function(e) {
     var petName = e.contexts[0]
     var person = e.contexts[1];
     this.get('content').pushObject({name: petName, person: person});
     // with ember-data:
     // App.Pet.createRecord({name: petName, person: person});
   }
});  
于 2012-10-04T22:35:05.907 に答える
1

コンセントを使用する必要があります。これらは、さまざまなコントローラーで処理できるEmberビューの小さな「プレースホルダー」です。

上記のリンクにそれらについての公正な説明がありますが、すでに確認して何も見つかりませんでした。しかし、それに戻る前に、まずこれを読んでください:http: //trek.github.com/

これらのいずれかがまだ役に立たない場合は、お知らせください。サンプルをまとめます。

于 2012-09-29T08:44:40.190 に答える
1

これはあなたが探しているものだと思います、見てください、それはかなり簡単です、あなたはこの例をチェックすることもできます。基本的に、すべてのコンセントを接続するためのコンセント、ルーター、およびアクションを使用して、目的を達成できます。

于 2012-10-04T15:56:12.987 に答える
0

私はEmberを初めて使用し、同様のことを行う方法を探していました。トップレベルのArrayControllerでは、itemControllerプロパティを使用しただけで、うまく機能しました。

App.PeopleController = Ember.ArrayController.extend({
    itemController: "Person"
});

App.PersonController = Ember.ObjectController.extend //...

私の完全な解決策は、このjsフィドルにあります。残念ながら、インスタンスを機能させる方法は私にはPetControllerハッキーに思えます。

于 2013-02-13T04:01:29.567 に答える