0
votes

I've been trying to figure this out for most of today and it's driving me insane, because I think i'm almost there, but just can't figure the last part out...

I have a route, called Map, which renders a sidebar, and within it has a named outlet for sidebar content:

map.hbs:

<div id="map-container">
    {{render sidebar}}
    <div id="map-canvas">
    </div>
</div>

... sidebar.hbs:

<div id="content-menu">
    {{outlet sidebar-content}}
</div>

Each menu item in my sidebar has a custom action called loadModule, which performs a render of a named view into the sidebar-content outlet (using {{action 'loadModule' 'sidebar.module'}}):

var MapRoute = App.AuthenticatedRoute.extend({
actions: {
    loadModule: function(module) {
        //load a valid view template into the view
        this.render(module, 
            {
                into: 'sidebar',
                outlet: 'sidebar-content'
            });
    }
}
});

module.exports = MapRoute;

Any action within the controller for that view works fine, I can trigger them from buttons etc, or by calling them in a didInsertElement in the SidebarModuleViews.

My issue is that I can't define a model for these views, so if I try and get data from my API in any of their Controllers, it won't render that data out to the templates.

I tried to use link-to, but I couldn't make the template append to the current viewport, rather than refreshing the entire page, which defeats the point of having a sidebar (I don't want the route to change)

var SidebarUserController = App.ApplicationController.extend({
actions: {
    doSomething: function() {
        alert('SOMETHING');
    },
    fetchUserProfile: function() {
        //do something
        var mod = this.store.find('profile', App.Session.get('uid'));
    }
}
});

I can trigger either of those actions from the rendered template once it's rendered, however, although my store updates with the record, the handlebars helpers in the sidebar/user.hbs do not populate with the model data.

Here is my model:

var Profile = DS.Model.extend({
uid: DS.attr('string'),
firstName: DS.attr('string'),
lastName: DS.attr('string'),
gender: DS.attr('string'),
DOB: DS.attr('date'),
email: DS.attr('string')
});

module.exports = Profile;

and here is my sidebar/user.hbs:

<div class="container">
    <button {{action 'doSomething'}}>Do A Thing</button>
    <h1>{{firstName}} {{lastName}}</h1>
    <h4>{{id}}</h4>
    {{#if isAuthenticated}}
        <a href="#" {{action 'logout'}}>Logout</a>
    {{/if}}
</div>

In that template, the firstName, lastName and id fields do not populate, even though i'm pulling the data from the API and successfully storing it.

Additionally, if it helps, my router.map for sidebar/user looks like this:

this.resource('sidebar', function() {
        this.route('user');
    });

I believe that the fundamental issue here is that I can't work out how to set the model for the controller without triggering the route. Am I going about this wrong?

1

1 Answers

0
votes

Ok so i've worked this out for my particular instance. It may not be the best way of doing it, but it's what I need:

In my MapRoute, I setup the model and controller for my additional sidebar menus in the setupController function. Doing this allows me to load critical data (such as user profile etc), on page load, and I can still retain the render function for each sidebar module in the Route, which will allow the intial data to load, and still allow me to update the model data for each sidebar module controller on subsequent functions:

map_route.js:

actions: {
        loadModule: function(module) {
            this.render(module, {into: 'sidebar', outlet: 'sidebar-content'});
        }
},
setupController: function(controller, profile) {
    var model = this.store.find('profile', App.Session.get('uid'));
    var controller = this.controllerFor('sidebar.user');
    controller.set('content', model);
},
...