Creating a new resource in ember

╄→尐↘猪︶ㄣ 提交于 2019-12-13 02:37:28

问题


I'm building an office reception app in Ember. When a person arrives at the office, they pop open the app and are taken through a three step wizard:

  • Choose a reason for visiting
  • Choose the person you've come to see
  • Confirm

The app also allows an administrator to view all of the visits and to view an individual visit.

I have Visit and Person models I've hooked up to a server using Ember Data. Here's what my routes look like:

App.Router.map () ->
  @resource 'visits', ->
    @resource 'visit', { path: '/:visit_id' }
    @resource 'new', ->
      @route 'welcome'
      @route 'directory'
      @route 'thanks'

This allows me to create a new Visit model in the VisitsNewRoute and use it in the welcome, directory and thanks views.

This works. However, it feels wrong to have a new resource, especially since it's conceivable I'll want at least one more new route in my application.

Is there a better way to do this?


回答1:


I think that you can change the new resource to newVisit like this:

App.Router.map () ->
  @resource 'visits', ->
    @resource 'visit', { path: '/:visit_id' }
  @resource 'newVisit', ->
    @route 'welcome'
    @route 'directory'
    @route 'thanks'

Now you will have a NewVisitRoute where you can create a new Visit model to use in each of the child routes.

And you will be able to make a transition to this routes with the route names: newVisit.welcome, newVisit.directory and newVisit.thanks. You can use this route names in a link-to helper link this:

{{link-to "Welcome", "newVisit.welcome"}}



回答2:


The recommended practice is to use a create/new route under the resource type, so new under visits, then `transitionTo('visit.welcome', newRecord). (I'm saying all of this with the assumption that welcome, directory, and thanks aren't part of the new record creation).

App.Router.map () ->
  @resource 'visits', ->
    @route 'new'
    @resource 'visit', { path: '/:visit_id' }
      @route 'welcome'
      @route 'directory'
      @route 'thanks'



回答3:


Ember doesn't always name routes the way you want when dealing with routes nested more than one level. I would name your 'new' route as follows:

@resource 'visits.new', path: 'new', ->

There are a number of approaches you can use to structuring your routes depending on how you assign model ids and whether or not you are using localStorage to preserve user edits until they are persisted to the server.

I have my route pattern as follows:

App.Router.map () ->
  @resource 'visits', ->
    @route 'new'
    @route 'crud', path: ':visit_id'

My 'new' routes create a new resource in the routes model callback which in my models auto-generates a v4 UUID. The new route then performs a transitionTo the crud route in the afterModel callback. In effect the 'visits.new' route acts as a trampoline and allows you to easily use {{link-to 'visits.new'}} from templates/menus etc.

The above approach allows you to to have a single crud route and crud controller that can handle all the show/create/update/delete actions for the model. The models isNew property can be used within your templates to handle any differences between create and update.

I also use localStorage so that newly created (but not yet persisted) models survive a browser refresh, the UUIDs really come in handy for both this and for persisting complex model graphs.

The above router pattern occurs quite a lot in my app so I have defined some base Route classes and a route class builder but the general pattern is as follows:

If using UUIDs:

App.VisitsNewRoute = Em.Route.extend
  model: (params, transition)->
    App.Visit.create(params)
  afterModel: (model,transition) ->
    @transitionTo 'visits.crud', model

App.VisitsCrudRoute = Em.Route.extend
   model: (params,transition) ->
    App.Visit.find(params['visit_id'])

If not using UUID's then the routes are different. I did something like this before I moved to UUIDs, it treats model id 'new' as a special case:

App.Router.map () ->
  @resource 'visits', ->
    @route 'crud', path: ':visit_id'

App.VisitsCrudRoute = App.Route.extend
   model: (params, transition) ->
     visit_id = params['visit_id']
     if visit_id == 'new' then App.Visit.create() else App.Visit.find(visit_id)
   serialize: (model, params) ->
     return if params.length < 1 or !model
     segment = {}
     segment[params[0]] = if model.isNew() then 'new' else model.get('id')
     segment

For your specific case of managing the wizard step state I would consider using Ember Query Params, which allow you specify the current step in a parameter at the controller level

Query params example:

App.VisitsCrudController = Em.ObjectController.extend
  queryParams: ['step'],
  step: 'welcome'

Link to next step in the view:

{{#link-to 'visits.crud' (query-params step="directory")}}Next{{/link-to}}

You may also want to define some computed properties for the next and previous steps, and some boolean properties such as isWelcome, isDirectory for your view logic.



来源:https://stackoverflow.com/questions/23947532/creating-a-new-resource-in-ember

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!