Question

We are developing educational platform. We have two resource types: courses and lessons. So we do have following URL schema:

/(root)
└┬course-slug
 ├─info
 └┬lesson-slug
  └┬comments
   └─comment-id

URL to a lesson looks like this: /programming/what-is-loop/ and comments for this lesson would have following URL: /programming/what-is-loop/comments/.

Now we decided that course is optional. Some lessons are not inside any course, some inside many courses. So new URL schema looks like this:

/(root)
├┬course-slug
│├─info
│└┬lesson-slug
│ └┬comments
│  └─comment-id
│
└┬lesson-slug
 └┬comments
  └─comment-id

In other words course part of URL are optional. How to make CourseRoute optional, or how to reuse LessonRoute, CommentsRoute and CommentRoute (in fact there is little more)

Était-ce utile?

La solution

Thx to all!

It turned out that easiest way is to move course-slug to query-params. Just few line of code needed to achive this:

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']

Because course property simply moved from lesson-model to controller no heavy refactoring needed in templates or somewhere else.

Autres conseils

If you're very sure about what you're doing -- that means on UI you have both standalone lesson and nested lesson under course -- you can do this way (hope you understand CoffeeScript, it's not hard):

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

@resource 'lesson', ->

This gives you different routes and urls. Then you can generate links like this:

{{link-to "Nested Lesson" "course.lesson" course lesson}}
{{link-to "Lesson" "lesson" lesson}}

This way, you have two lesson routes that can not be the same. You can use inheritance or mixin to reuse functionalities, like use the same controller/view/template.

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

For comments, if you wish, you can use the same way. But I think you don't really need to define a url for comment. In this way you can just use setupController and renderTemplate to render CommentsController to 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.

And your lesson template:

{{outlet comments}}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top