2013-07-15 6 views
8

ネストされたアウトレットがemberテンプレートで動作する方法を説明してもらえますか?特にEmber JSとEmber Railsのネストされたルート

ドキュメントからこれを理解しよう: http://emberjs.com/guides/routing/rendering-a-template/

を「即時親ルートが...メインコンセントにレンダリングされませんでした」これは、現在のルートをレンダリングしようとしたことを意味ルートルートのテンプレートに親ルートがテンプレートをレンダリングしなかったか、親ルートが提供したテンプレートが がデフォルトの{{outlet}}にレンダリングしなかった場合、 })。

具体的には、私のアプリでネストされたビュー階層を作成する方法を理解しようとしています。 コレクションの3層深いです。コレクションの内容に基づいて、一連の折りたたみ可能なネストされたビューを作成したいと考えています。データ構造はツリーのようなものです。

ライブラリ - >各図書館には多くの本を持っている - >各ブックは、実際には、ネストされたテンプレート構造を示して説明jsbinやコードサンプルを探して多くのページ

を持っています。

次のようになり、ルータを想像:一般的なほとんどのテンプレート言語で

App.Router.map(function() { 

    this.resource('libraries', function() { 
     this.route('new'); 

     this.resource('library', {path: ':library_id'}, function() { 

      this.resource('books', function() { 
       this.route('new'); 
       this.resource('book', {path: ':book_id'}, function() { 

        this.resource('pages', function() { 
         this.route('new'); 
         this.resource('page', {path: ':page_id'}, function() { 

         }); // Page 
        }); // Pages 

       }); // Book 
      }); // Books 

     }); // Library 
    }); // Libraries 

}); // map 

答えて

10

はメインレイアウトにページのtarget内容をラップするためにいくつかの方法を提供します。これにより、共通のページレイアウトを別のファイルに分割し、小さなターゲットテンプレートを別のファイルに分割することができます。

Emberでこれを数回反復しましたが、現在のところ、この機能は{{outlet}}ヘルパーによって提供されています。アウトレットはEmberからyieldへのレイアウトです。

outletが大きく広がる領域は、yieldと重複しています。サーバーサイドでの収穫ははるかに簡単です。テンプレートの領域にマークしてから、指定されたターゲットにコンテンツのブロックを生成するために呼び出す必要があります。

しかし、コンテンツのレンダリングがクライアント側のJavaScriptに切り替えられた場合、必要に応じてページの一部だけが更新されます。単にマーカーyieldに直接入れることはできません。あなたはもっとスマートなyieldが必要です: - outlet

{{outlet}}には2つの辺があります。

  1. 降伏したい場所を示すマーカー。これは{{outlet}}ヘルパーです。
  2. このアウトレットにテンプレートをレンダリングするコード。これは、renderTemplateフック内で使用されるrenderメソッドです。

デフォルトでは、{{outlet}}は名前を必要としません。これにより、そのテンプレートのデフォルト出口になります。テンプレートには多数のアウトレットがあり、名前を付けることで指定できます。たとえば: -

{{outlet 'sidebar'}} 
{{outlet 'nav'}} 

これは、 'sidebar'と 'nav'という2つのアウトレットを宣言しています。これらのアウトレットに他のテンプレートをレンダリングできるようになりました。

デフォルトのアウトレットは、アウトレット名が明示されていない場合に使用されます。指定されたアウトレットについては、レンダリングはrenderTemplateフックのrenderRouteと呼んで行います。 オプションとしてrenderメソッドに渡されたハッシュにoutletオプションを指定することでこれを実行します。ここで

renderTemplate() { 
    this.render('recentPosts', { outlet: 'sidebar' }); 
} 

、テンプレートrecentPostsは、その親テンプレート内の「サイドバー」という名前のコンセントにレンダリングされます。

ルートが他のネストされたルートの中にネストされている場合、ルートは最も近い親アウトレットにレンダリングされます。親リソースにデフォルトのアウトレットがない場合は親が使用され、applicationテンプレートに達するまで続きます。

resourcethis.resource('posts');と宣言すると、規約に基づいていくつかのことが示されます。

  1. レイアウトテンプレートpostspostsルートをレンダリングします。
  2. オプションで、暗黙のposts.indexルートをテンプレートposts/indexでレンダリングします。

postsテンプレートには、すべての投稿とそのサブリソースに共通のレイアウトが含まれています。最低でも、少なくとも{{outlet}}のようなデフォルトのコンセントを含む必要があります。

これがない場合、{{outlet}}子ルートには、すぐにレンダリングする親コンセントはありません。彼らはその親の親をレンダリングするか、最終的にテンプレートのアウトレットをレンダリングします(application)。これが起こると、"The immediate parent route did not render into the main outlet ..."の警告が表示されます。この場合、outletsの場所を確認してください。

posts.indexは、ネストされたルートを持つすべてのリソースに与えられる暗黙のルートです。つまり、リソースにネストされたルートがある場合は、ネストされた、this.route('index) `を明示的に宣言する必要はありません。

このindexルートは、そのリソースの内容を表示できます。たとえば、posts.indexの場合、すべてpostsのリストを表示できます。この暗黙的なルートを持つ2番目の注意点は、モデルが親のpostsルート上にあることです。 PostsIndexControllerでこのモデルを取得するには、needs APIを使用する必要があります。

さらに、このposts.indexルートはオプションです。投稿のリストを表示するために使用されるposts/indexのUIをpostsテンプレート自体に直接配置することができます。しかし、これはどんな子リソースもpostsの出口に沿って、投稿のリストでレンダリングすることを意味します。明示的なインデックスルートを使用するかどうかの決定は、表示する必要があるUIによって異なります。

上記以外のテンプレートには、applicationというテンプレートがあります。ネストされたリソースをレンダリングするためにはoutletが必要で、通常はページに共通のレイアウトが格納されます。アプリケーションテンプレートを指定しない場合は、デフォルトのテンプレートが使用されます。この生成されたテンプレートは、{{outlet}}に相当します。 - デフォルトのアウトレットのみを持つテンプレート。

以下の経路を考慮してください。ここで

App.Router.map(function() { 
    this.resource('posts', function() { 
     this.route('new') 
     this.resource('post', {path: ':post_id'}, function() { 
     this.resource('comments', function() { 
      this.route('new'); 
     }); 
     }); 
    }); 
}); 

posts.newapplicationテンプレートのデフォルトのコンセントにレンダリングされます posts内部でレンダリングされます posts、にレンダリングされます。残りのテンプレートは次のとおりです。

+---------------------------+--------------------------------------------------------+ 
| Route      | Templates used (default outlets)      | 
+---------------------------+--------------------------------------------------------+ 
| posts.index    | posts.index > posts > application      | 
+---------------------------+--------------------------------------------------------+ 
| posts.new     | posts.new > posts > application      | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.index   | post.index > post > posts > application    | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.new   | post.new > post > posts > application     | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.comments.index | comments.index > comments > post > posts > application | 
+---------------------------+--------------------------------------------------------+ 
| posts.post.comments.new | comments.new > comments > post > posts > application | 
+---------------------------+--------------------------------------------------------+ 

このデフォルトのテンプレート階層はrender方法にintoオプションを指定することで変更することができます。ここで

renderTemplate: function() { 
    this.render('posts', { into: 'sidebar' }) 
} 

postsテンプレートはsidebarテンプレートのデフォルトのコンセントにレンダリングされます。

それはそれです。 Outletは、設定よりも多くの慣例を使用する別のエバーコンセプトです。デフォルトは非常に優れており、同時にカスタマイズも簡単です。

+0

Darshanの概要をありがとう。 Route - > Templatesテーブルは、何かを明確にするのに役立ちます。私は完全にそれをgrokする前に、私はこのカップルより多くの時間を読むでしょう。ネスティングの振る舞いについては、私の心の中でまっすぐにする必要があります。 –

+0

ここで、「posts.post.new」というルートを定義しましたか? –

+0

@Darshanあなたはemberjsのルーターの挙動にも対処するという私の質問を見ることができますか? http://stackoverflow.com/questions/17780344/nested-routing-behavior-for-ember-js –

関連する問題