2012-09-26 17 views
10

私はEmberJS v1.0.preでアプリを書いています。私はすべての人のリストを含むArrayControllerを持っています。人、ペット、各ペットのメモを表示するネストされたビューの束があります。そこにそれぞれの子のためのコントローラでなければなりませんが、私はエンバーでそれを達成する方法を見つけ出すことができないようにそれは感じている純粋なMVCの観点からEmberJSネストされたビューとコントローラ

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

。上位のアレイコントローラーがあり、すべての個々のビューがあります。メモを削除したり、編集したりする場合は、ビューのコンテキストをコントローラに渡す必要があるようです。

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

これは本当に悪いと感じます。ビューは、データの正式なソースではないと考えられます。私の前提は、ArrayControllerはitemViewClassと一緒にitemControlerClassをインスタンス化するということです。

更新日:私はfiddleを作成して、私の問題をより詳しく説明しました。この機能は意図的に不完全であり、リスト上の項目がクリックされたときに内容を増やして機能を終了させることが目的です。

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

+0

これを経由してくださいhttp://emberjs.com/guides/outlets/ –

+0

私の問題については、このガイドに実際の企業情報はありません。私はそれを前に読んだことがありますが、私はそれを参照し続けますが、まだ何も見つかりませんでした。 – noazark

+0

これをチェックしてくださいhttp://stackoverflow.com/questions/12595496/how-can-i-build-a-recursive-view-in-ember/12602743#comment17008361_12602743 –

答えて

12

(人物、ペット、ノート)。ちなみに、子オブジェクト(犬、メモ)に対するアクションはApp.PersonsControllerに渡すべきではありません。それはSeparation of Concernsの原則を破るでしょう。

Ember.Router docsは、1つのオブジェクトにビューをネストする場合をカバーします(例:/:people_id)。しかし、オブジェクトの配列のビューを入れ子にしたいとします。

3人のArrayControllerのPerson、Pets、Notesをロードし、子オブジェクトのアクションを対応する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}} 

、子オブジェクト上のアクションがそのコントローラ(ペット - > 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}); 
    } 
}); 
+1

これは簡単に私の問題を見てきた最も完全な例です、ありがとう!私はこの答えを取ってそれを実行します。私はまだ対処する必要があるいくつかの問題があります。ビューからコンテキストを渡すことは、この問題に対する私の最初の苦情ですが、避けられないようです。また、コントローラーはペット(文字通り埋め込まれている)の子であり、ペットと人と同じであるため、単純にすべてのNotesに設定することはできません。私には、これは建築上の問題のようには感じられません。最初に親コンテキストを設定する必要があります。もっと私が見つけたもので私の質問を更新します。再度、感謝します。 – noazark

1

アウトレットを使用する必要があります。 Emberビューでは、異なるコントローラーで処理できる小さな「プレースホルダー」です。

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

これらのいずれかがあなたに役に立たない場合は、私に知らせてください。

+0

私の記事の前にも、私は両方の記事を読んだことがあります。私もアウトレットを使用していますが、アウトレットはコンテンツの責任を別のコントローラに委任しません。あなたのオファーが例を挙げてくれてありがとう、私はそれを見たいと思っています。私は私の問題をよりよく説明するためにjsfiddleで何かを鞭打ちます。 – noazark

+0

私は[フィドル](http://jsfiddle.net/noazark/HmHK3/)で質問を更新しました。あなたの継続していただきありがとうございます。 – noazark

1

私はthisがあなたの探しているものだと思っています。それはかなりまっすぐです。thisの例もチェックできます。基本的には、アウトレット、ルーター、すべてのアウトレットを接続するためのアクションで必要なものを達成することができます。あなたがオブジェクトのコレクションごとに各項目のためのコントローラを必要とするが、代わりにArrayControllerない「と、それぞれの子のためのコントローラがあるべきようにそれは感じている純粋なMVCの観点から」

+0

私はそれをもう一度奪うでしょう。この記事(https://gist.github.com/3002177)も大きな助けになりました。私の問題はArrayControllerを使用していると思います。本当にそれはちょうど店舗を持つコントローラにする必要がありますか?それは理にかなっていますか? – noazark

+0

あなたは、より適切な別の例を提供することができますか?あなたが提供したものは私の質問と並行していません。具体的には、私の問題はルーティングではなく、ネストされたリソースへのコントロールの委任に関するものです。アウトレットは面白いですが、それらを使用するためのすべての提案があっても、私の問題をどのように解決するのかという有用な例はまだありません。 – noazark

0

私はエンバーに新たなんだと似た何かをする方法を探してきました。トップレベルArrayControllerでは、私はちょうどitemControllerプロパティを使用し、それは素晴らしい仕事:

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

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

私の完全なソリューションをthis js fiddleです。残念ながら、私がPetControllerのインスタンスを動作させる方法は、私にとってはハッキリです。

+0

v1.0preからの更新は非常に役立ち、私はもっと良い運があった。あなたがしたことをさらに深く掘り下げ、それがどうなるかを見てみましょう! – noazark

関連する問題