Ember.js 可选路由(URL部分)

Ember.js 可选路由(URL部分),ember.js,ember-router,Ember.js,Ember Router,我们正在开发教育平台。我们有两种资源类型:课程和课程。因此,我们有以下URL模式: /(root) └┬course-slug ├─info └┬lesson-slug └┬comments └─comment-id 换句话说,URL的课程部分是可选的。如何使CourseRoute可选,或者如何重用LessonRoute、CommentsRoute和CommentRoute(事实上没有更多)如果您非常确定自己在做什么——这意味着在UI上,课程下既有独立的课程,也有嵌套的课程——您可

我们正在开发教育平台。我们有两种资源类型:课程课程。因此,我们有以下URL模式:

/(root) └┬course-slug ├─info └┬lesson-slug └┬comments └─comment-id
换句话说,URL的课程部分是可选的。如何使
CourseRoute
可选,或者如何重用
LessonRoute
CommentsRoute
CommentRoute
(事实上没有更多)

如果您非常确定自己在做什么——这意味着在UI上,课程下既有独立的课程,也有嵌套的课程——您可以这样做(希望你能理解咖啡脚本,这并不难):

这将为您提供不同的路由和URL。然后您可以生成如下链接:

/(root) ├┬course-slug │├─info │└┬lesson-slug │ └┬comments │ └─comment-id │ └┬lesson-slug └┬comments └─comment-id
{{link-to "Nested Lesson" "course.lesson" course lesson}}
{{link-to "Lesson" "lesson" lesson}}
这样,您就有了两个不同的课程路线。您可以使用继承或混合来重用功能,例如使用相同的控制器/视图/模板

App.LessonRoute = Em.Route.extend
  controllerName: 'lesson'
  templateName: 'lesson'   # Or use viewName if you need to define a view

  model: ->
    # get lesson

App.CourseLessonRoute = App.LessonRoute.extend
  model: ->
    # get lesson from course

# No need to define "CourseLessonController"
App.LessonController = Em.ObjectController.extend()
对于评论,如果您愿意,可以使用相同的方法。但是我认为您实际上不需要定义评论的url。这样,您只需使用
setupController
renderTemplate
commentscoontroller
呈现到
comments outlet

App.LessonRoute = Em.Route.extend
  setupController: (controller, model) ->
    @_super.apply(@, arguments)

    comments = model.get('comments') # Just an example code to get comments
    @controllerFor('comments').set 'model', comments

  renderTemplate: ->
    @_super.apply(@, arguments)

    @render 'comments',
      into: 'lesson'
      outlet: 'comments'
      controller: 'comments'  # Not sure if this option can be ignored.
以及您的
课程
模板:

{{outlet comments}}
谢谢大家

事实证明,最简单的方法是移动
课程slug
查询参数。只需几行代码即可实现此目的:

App.LessonRoute = Em.Route.extend
  setupController: (controller, model, transition)->
    controller.set 'content', model

    course_slug = transition.queryParams.scope
    if course_slug
      ...
      @get('store').find('course', course_id).then (course)->
        controller.set 'course', course

App.LessonController = Em.ObjectController.extend
  scope: null # slug for course
  queryParams: ['scope']

因为
course
属性只是从课程模型移动到控制器,不需要在模板或其他地方进行繁重的重构。

鉴于此URL方案,我要做的是通过复制模型的renderTemplate钩子重用视图和控制器routes@MeoriOransky是的,但是如何处理URL呢?例如在templa中我经常使用
{{link to}}
并且我不能保留旧的路由名称。我需要根据当前路由使用不同的路由名称。您可以使用一个条件(不是一种非常干净的方式),或者您可以扩展link to和LinkView来创建一个{{link to lesson}帮助器,该帮助器可以智能化。以及{{{link to comments}{{{#链接到评论}}和所有其他…但无论如何thx。也许我会想出通用的{{#智能链接到}。而且我正在考虑移动
课程slug
来查询参数。这个URL模式是一个等待发生的噩梦。为什么不让
lessson slug
始终是“第一个”路线?对我来说,保持一致更有意义。您的路线可以是
/course slug
/course slug/info
/lessue slug
/lessue slug/comments
/lessue slug/comments/:comment\u id
。假设
lessue slug
在整个应用程序中始终是唯一的。然后l
#链接到lesson slug lesson
将保持一致,不需要疯狂的url逻辑。thx!非常有趣,但url是评论的必选链接(例如,我们必须发送带有链接的邮件通知)。并且
评论
不是唯一的“嵌套”路径内课。这种解决方案是不可伸缩的。您应该只在UI嵌套时使用嵌套资源。注释可能存在于许多页面中,并且可以被视为应用程序状态的一部分。如果您想在url中表示该状态,那么查询参数比嵌套资源更好。购买时您必须使用金丝雀版本。我刚刚使用过它出于同样的原因。它比你想象的更稳定。检查此链接以获取查询参数
App.LessonRoute = Em.Route.extend
  setupController: (controller, model, transition)->
    controller.set 'content', model

    course_slug = transition.queryParams.scope
    if course_slug
      ...
      @get('store').find('course', course_id).then (course)->
        controller.set 'course', course

App.LessonController = Em.ObjectController.extend
  scope: null # slug for course
  queryParams: ['scope']