了解Ember路线

时间:2013-05-12 18:23:52

标签: ember.js ember-router

假设我有这样的路线图:

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}}中。我可以emtpy {{outlet}}每个新路线,但然后它会突破按钮,因为Ember不会再次渲染上一个模板,假设已经渲染了。

所以问题是如何对不同的路由使用单{{outlet}}并且不破坏余烬的逻辑。当然,我可以避免使用嵌套路由,但是当你需要像post/2/comment/12/edit这样的语义链接时它们非常有用。

2 个答案:

答案 0 :(得分:3)

如果您的模板没有嵌套,则不应嵌套您的路线,否则您将最终与Ember作战。作为Ember的州经理,路线描述您的应用程序结构。嵌套应该遵循您的用户界面,而不是您希望网址的样子。

如果您关注的是网址,则可以修改path以满足您的需求:

App.Router.map ->
  @resource 'posts'
  @resource 'post', { path: 'posts/:post_id' }

答案 1 :(得分:0)

即使我的路由是嵌套的,我用来处理嵌套和非嵌套模板的方法是使用命名出口。 Ember让它变得非常简单。

我有一个顶级菜单插座,它始终包含与所访问路线相关的菜单。

示例应用程序模板:

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

您不必像上面那样进行默认的嵌套渲染,您只需定义一个始终渲染到命名插座的路径类型,例如“content”(只是不要将其称为“main”,因为Ember使用了)。

App.ContentRoute = Em.Route.extend
  renderTemplate: (controller, model)->
    @render outlet: "content", into: "application"

然后从它中继承任何应该总是呈现到应用程序'content'出口的路由:

App.PostsIndexRoute = App.ContentRoute.extend()
App.CommentsIndexRoute = App.ContentRoute.extend()

但最好使用mixin来实现,这样您就可以轻松地将任何您想要的问题包含在任何路径中(例如,经过身份验证的路线问题)。

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