Понимание Ember маршрутов
Предположим, у меня есть маршрутная карта, как это:
App.Router.map ->
@resource 'posts', ->
@resource 'post', {path: '/:post_id'}
Так что у меня есть список постов на /posts
маршрут и один пост на posts/2
, По умолчанию posts
шаблон будет отображаться в {{outlet}}
родительского шаблона (application
) что в порядке и post
шаблон для {{outlet}}
из posts
шаблон, который не то, что я хочу. Я хочу заменить список постов одним постом.
Таким образом, я пришел с этим решением, чтобы установить желаемый шаблон для рендеринга к нему {{outlet}}
:
App.PostRoute = Em.Route.extend
renderTemplate: ->
this.render(into: 'application')
Но в результате у меня есть список постов и один пост в одном {{outlet}}
, Я могу сделать {{outlet}}
каждый новый маршрут, но затем он ломает кнопку "назад", потому что Ember не будет отображать предыдущий шаблон снова, предполагая, что он уже обработан.
Так что вопросы, как использовать один {{outlet}}
для разных маршрутов и не нарушайте логику Эмбер. Конечно, я могу избежать вложенных маршрутов, но они действительно полезны, когда вам нужны такие семантические ссылки post/2/comment/12/edit
,
2 ответа
Если ваши шаблоны не являются вложенными, вы не должны вкладывать свои маршруты, иначе вы закончите борьбу с Ember. Действуя как менеджер состояния Ember, маршруты описывают структуру вашего приложения. Вложенность должна соответствовать вашему интерфейсу, а не тому, как вы хотите, чтобы ваши URL выглядели.
Если ваша проблема связана с URL, вы можете просто изменить path
чтобы соответствовать вашим потребностям:
App.Router.map ->
@resource 'posts'
@resource 'post', { path: 'posts/:post_id' }
Подход, который я использовал для обработки вложенных и не вложенных шаблонов, даже когда мои маршруты вложенные, заключается в использовании именованных выходов. Эмбер делает это действительно легко.
У меня есть пункт меню верхнего уровня, который всегда содержит меню, относящееся к посещаемому маршруту.
Пример шаблона приложения:
<div id="nav">
{{partial "nav"}}
</div>
<div id="menu">
{{outlet "menu"}}
</div>
<div id="main">
{{outlet}}
</div>
{{outlet "modal"}}
У меня есть два названных выхода, "menu" и "modal", которые используются для хранения контента, который не является вложенным, но используется для вложенных маршрутов или любого маршрута, если быть точным. Любой маршрут может визуализировать модальное в ответ на действия в глобальном "модальном" выходе, и аналогично любой маршрут может отображать меню в "меню".
Мои примеры используют coffeescript.
маршрутизатор:
App.Router.map ->
@resource "posts", ->
@route "create"
@resource "post", {path: ':id'}, ->
@resource "comments", {path: ':id'}, ->
@route "create"
@resource "comment", {path: ':id'}, ->
Маршруты, которые отображают меню в именованный выход, который не является вложенным:
App.PostsIndexRoute = Em.Route.extend
renderTemplate: (controller, model)->
# default render
@_super arguments...
# render posts menu into the application menu outlet
@render "posts.menu",
outlet: "menu"
into: "application"
App.CommentsIndexRoute = Em.Route.extend
renderTemplate: (controller, model)->
# default render
@_super arguments...
# render comments menu into the application menu outlet
@render "comments.menu",
outlet: "menu"
into: "application"
Вам не нужно делать вложенный рендеринг по умолчанию, как описано выше, вы можете просто определить тип маршрута, который всегда рендерится в именованный выход, такой как "контент" (просто не называйте его "основным", потому что это использует Ember).
App.ContentRoute = Em.Route.extend
renderTemplate: (controller, model)->
@render outlet: "content", into: "application"
И затем подкласс от него для любых маршрутов, которые всегда должны отображаться в приложении "контент":
App.PostsIndexRoute = App.ContentRoute.extend()
App.CommentsIndexRoute = App.ContentRoute.extend()
Но было бы лучше сделать это с помощью миксина, чтобы вы могли легко включить любые проблемы, которые вы хотите, в любой маршрут (например, аутентифицированные проблемы маршрута).
App.RenderIntoContent = Em.Mixin.create
renderTemplate: (controller, model)->
@render outlet: "content", into: "application"
App.PostsIndexRoute = Em.Route.extend App.RenderIntoContent,
...
App.CommentsIndexRoute = Em.Route.extend App.RenderIntoContent,
...