Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request to support { model: my_model } in this.render() on a route #1820

Closed
Nopik opened this issue Jan 19, 2013 · 5 comments
Closed

Request to support { model: my_model } in this.render() on a route #1820

Nopik opened this issue Jan 19, 2013 · 5 comments

Comments

@Nopik
Copy link
Contributor

Nopik commented Jan 19, 2013

There was some discussion about it in #1635 (and maybe others), I'd like to provide more use cases for this. Namely, in my existing code (~230 lines of coffeescript for routing), supporting that { model: ... } syntax would reduce my code by ~10%.

I'll post vast majority of my routing code below, so you can see yourself - and probably point me few code smells along the way, too ;) Especially, that I'm putting too much into renderTemplate() instead of using setupController().

The vast majority of the cases I'm using several render() calls in renderTemplate() are:

  1. having global navigation menu, where each sub-screen renders its own navigation items
  2. having one controller/view shared across several routes

Basically my dashboard views have {{outlet main}} and {{outlet menu}}, which gets populated with various things.

In the snippet below, about 20 lines out of 130 is just to substitue { model: } behaviour. Interestingly, in the old router, connectOutlet() was doing the 'right' thing - in this point of view, new router introduced degradation (but, overall my code was 20% shorter after porting to the new router anyway!).

So, here is about 50% of my code (I did cut about half of the routes, almost all the events and transitions, too):

App.Router.map ->
    @route 'home', { path: '/' }

    @resource 'dashboard', { path: "/#{get_user_info().slug}" }, ->
        @resource 'workspace', { path: '/:workspace_slug' }, ->
            @route 'appinstance', { path: '/:appinstance_slug' }

    @resource 'public_dashboard', { path: '/:user_slug' }, ->
        @resource 'public_workspace', { path: '/:workspace_slug' }, ->
            @route 'public_appinstance', { path: '/:appinstance_slug' }

App.HomeRoute = Ember.Route.extend
    setup: ->
        @transitionTo 'dashboard'

App.DashboardRoute = Ember.Route.extend
    setupController: (controller, context)->
        controller.fetchDashboard()

    renderTemplate: (controller, model)->
        @render 'dashboard', { into: 'application' }

        dmic = @controllerFor( 'dashboardMenuitems' )
        dmic.set 'content', controller.workspaces
        @render 'dashboardMenuitems', { into: 'dashboard', outlet: 'menu' }
        #Previously I also had to use: controller: dmic here. Fortunately recently it got easier.

        dbc = @controllerFor( 'dashboardBoxes' )
        dbc.set 'content', []
        @render 'dashboardBoxes', { into: 'dashboard', outlet: 'main' }

    events:
        goToWorkspace: (ws)->
            @transitionTo 'workspace', ws

App.PublicDashboardRoute = Ember.Route.extend
    model: (params)->
        uc = @controllerFor( 'user' )
        uc.getUser( params.user_slug ) #Code smell, should fetch from User store

    renderTemplate: (controller, user)->
        user.fetchWorkspaces() #Probably not good place for this, either ;)

        @render()

        dmic = @controllerFor( 'dashboardMenuitems' )
        dmic.set 'content', user.workspaces
        @render 'dashboardMenuitems', { into: 'public_dashboard', outlet: 'menu' }

        dbc = @controllerFor( 'dashboardBoxes' )
        dbc.set 'content', []
        @render 'dashboardBoxes', { into: 'public_dashboard', outlet: 'main' }

    events:
        goToWorkspace: (ws)->
            @transitionTo 'public_workspace', ws

    serialize: (user)->
        { user_slug: user.get( 'slug' ) }

App.PublicWorkspaceRoute = Ember.Route.extend
    model: (params)->
        user = @modelFor( 'public_dashboard' )
        workspace = user.getWorkspaceBySlug( params.workspace_slug )
        workspace

    renderTemplate: (controller, workspace)->
        #No 'standard' render at all...
        dbc = @controllerFor( 'dashboardBoxes' )
        dbc.set 'content', workspace.app_instances
        @render 'dashboardBoxes', { into: 'public_dashboard', outlet: 'main' }

    serialize: (workspace)->
        { workspace_slug: workspace.get( 'slug' ) }

    events:
        goToAppInstance: (appinst)->
            @transitionTo 'public_workspace.public_appinstance', appinst

App.PublicWorkspaceIndexRoute = Ember.Route.extend
    renderTemplate: (controller)->
        workspace = @modelFor( 'public_workspace' )

        dbc = @controllerFor( 'dashboardBoxes' )
        dbc.set 'content', workspace.app_instances
        @render 'dashboardBoxes', { into: 'public_dashboard', outlet: 'main' }

App.PublicWorkspacePublicAppinstanceRoute = Ember.Route.extend
    model: (params)->
        workspace = @modelFor( 'public_workspace' )
        workspace.getAppInstanceBy( 'slug', params.appinstance_slug )

    renderTemplate: (controller, appinst)->
        aic = @controllerFor( 'public_appinstance' )
        aic.set 'content', appinst
        @render 'appInstance', { into: 'public_dashboard', outlet: 'main', controller: aic }

    serialize: (appinst)->
        { appinstance_slug: appinst.get( 'slug' ) }

App.WorkspaceRoute = Ember.Route.extend
    model: (params)->
        dc = @controllerFor( 'dashboard' )
        dc.getWorkspaceBySlug( params.workspace_slug )

    renderTemplate: (controller, workspace)->
        dbc = @controllerFor( 'dashboardBoxes' )
        dbc.set 'content', workspace.app_instances
        @render 'dashboardBoxes', { into: 'dashboard', outlet: 'main' }

    serialize: (workspace)->
        { workspace_slug: workspace.get( 'slug' ) }

App.WorkspaceIndexRoute = Ember.Route.extend
    renderTemplate: (controller)->
        workspace = @modelFor( 'workspace' )

        dbc = @controllerFor( 'dashboardBoxes' )
        dbc.set 'content', workspace.app_instances
        @render 'dashboardBoxes', { into: 'dashboard', outlet: 'main' }

App.WorkspaceAppinstanceRoute = Ember.Route.extend
    model: (params)->
        workspace = @modelFor( 'workspace' )
        workspace.getAppInstanceBy( 'slug', params.appinstance_slug )

    renderTemplate: (controller, appinst)->
        aic = @controllerFor( 'app_instance' )
        aic.set 'content', appinst
        @render 'app_instance', { into: 'dashboard', outlet: 'main' }

    serialize: (appinst)->
        { appinstance_slug: appinst.get( 'slug' ) }
@wycats
Copy link
Member

wycats commented Jan 28, 2013

You should be able to do:

@controllerFor( 'dashboardMenuitems' ).set('content', controller.workspaces)
@render 'dashboardMenuitems', { into: 'dashboard', outlet: 'menu' }

I'm not comfortable adding additional sugar quite yet. We can revisit shortcuts for Ember 1.1 once we see a lot more real-world usage.

Thanks for your feedback. I will keep it in mind when we circle back around!

@wycats wycats closed this as completed Jan 28, 2013
@mbykovskyy
Copy link

@wycats Doing so will require the dashboardMenuItems controller to be explicitly defined. In my case all I want is render the model in the template. At the moment I have to create an empty controller.

@rwjblue
Copy link
Member

rwjblue commented May 16, 2014

I believe that render accepts the model now (relatively recent change, not sure which stable version it will be in).

@selvagsz
Copy link

[FEATURE ember-routing-add-model-option] is available since 1.6.0-beta.1

@rwjblue
Copy link
Member

rwjblue commented May 19, 2014

@selvagsz - thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants