【问题标题】:Optional route (URL part)可选路由(URL 部分)
【发布时间】:2014-08-22 01:08:18
【问题描述】:

我们正在开发教育平台。我们有两种资源类型:课程课程。所以我们确实有以下 URL 架构:

/(根) └┬课程-蛞蝓 ├─资讯 └┬上课-蛞蝓 └┬cmet └─comment-id

课程的 URL 如下所示:/programming/what-is-loop/,而本课程的 cmets 将具有以下 URL:/programming/what-is-loop/comments/

现在我们决定该课程是可选的。有些课程不在任何课程中,有些课程在许多课程中。所以新的 URL 架构如下所示:

/(根) ├┬课程-蛞蝓 │├─资讯 │└┬教训-蛞蝓 │ └┬cmets │ └─comment-id │ └┬上课-蛞蝓 └┬cmet └─comment-id

换句话说,URL 的 course 部分是可选的。如何使CourseRoute可选,或者如何重用LessonRouteCommentsRouteCommentRoute(其实还有一点)

【问题讨论】:

  • 我会做什么 - 给定这个 URL 方案,是通过重复路由的 renderTemplate 钩子重用视图和控制器
  • @MeoriOransky 是的.. 但是如何处理 url?例如,在模板中,我经常使用{{link-to}},但我不能保留旧的路由名称。我需要根据当前路线使用不同的路线名称
  • 您可以使用条件(不是一种非常干净的方式),也可以扩展链接到和 LinkView 以创建一个可以智能的 {{#link-to-lesson}} 助手它。
  • 以及 {{#link-to-cmets}} {{#link-to-comment}} 和所有其他人......但无论如何,谢谢。也许我会想出一般的{{#smart-link-to}}。另外我正在考虑将course-slug 移动到查询参数。
  • 这个 URL 架构是一场等待发生的噩梦。为什么不将lessson-slug 始终设为“第一”路线?保持这种一致性对我来说更有意义。您的路线可以是/course-slug/course-slug/info/lesson-slug/lesson-slug/comments/lesson-slug/comments/:comment_id。假设lesson-slug 在整个应用程序中始终是唯一的。那么所有的#link-to lesson-slug lesson 都会保持一致,不需要疯狂的 url 逻辑。

标签: ember.js ember-router


【解决方案1】:

谢谢大家!

事实证明,最简单的方法是将course-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 属性只是从课程模型转移到控制器,不需要在模板或其他地方进行大量重构。

【讨论】:

    【解决方案2】:

    如果你非常确定自己在做什么——这意味着在 UI 上你有独立课程和嵌套课程——你可以这样做(希望你理解 CoffeeScript,这并不难):

    @resource 'course', path: ':course_id', ->
      @route 'info'
      @resource 'course.lesson', ':lesson_id' ->
    
    @resource 'lesson', ->
    

    这为您提供了不同的路线和网址。然后你可以生成这样的链接:

    {{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()
    

    对于 cmets,如果您愿意,可以使用相同的方式。但我认为你真的不需要定义一个 url 来发表评论。这样你就可以只用setupControllerrenderTemplateCommentsController渲染成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.
    

    还有你的lesson 模板:

    {{outlet comments}}
    

    【讨论】:

    • 谢谢!非常有趣,但 url 对于 cmets 是强制性的(例如,我们必须发送带有链接的邮件通知)。而comments 并不是课程内“嵌套”的唯一路线。这种解决方案不可扩展。
    • 只有在 UI 嵌套时才应该使用嵌套资源。评论可能存在于许多页面中,它可以被视为申请状态的一部分。如果您想在 url 中表达该状态,那么查询参数是比嵌套资源更好的选择。购买你必须使用金丝雀版本。我只是出于同样的原因使用它。它比你想象的更稳定。
    • 查看此链接查询参数emberjs.com/guides/routing/query-params
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    • 2022-10-02
    • 2010-12-07
    • 2016-07-17
    • 2019-12-05
    • 2020-08-28
    相关资源
    最近更新 更多