Понимание 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,
  ...
Другие вопросы по тегам