Urnitemare Urnitemare - 6 months ago 43
Javascript Question

Ember.js -Render a template in separate directory with own controllers

I am not understanding the correct way to render a template inside another template. I am using ember-cli 2.4.3.

I have my route.js:

import Ember from 'ember';
import config from './config/environment';

const Router = Ember.Router.extend({
location: config.locationType
});

Router.map(function() {
this.route('index', {
path: '/'
});
this.route('nodes', function() {
this.route('detail', {
path: '/:node_id'
}
});
this.route('widgets', function() {
this.route('node_list');
});
});

export default Router;


I have my outlet in my index.js:

<!-- app/templates/index.hbs -->
{{outlet node_list}}


So far this is what I have in my index.js route:

// app/routes/index.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
renderTemplate: function() {
this.render();
this.render('index');
this.render('widgets/project_list', {
into: 'index',
outlet: 'node_list',
controller: 'nodes/index'
});
}
});


And my controller that I am trying to reference is at
app/controllers/nodes/index.js
, but I am not sure if that is correct. The only thing I have in my controls regard creating, deleting, and destroying nodes, which actually I am just trying to get a node list. It would be based on the node models, which is in a separate ember project library that gets accessed through the nodes.js route:

// app/routes/nodes.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
store: Ember.inject.service(),
session: Ember.inject.service(),
model() {
let user = this.modelFor('application');
if (user) {
return user.get('nodes');
} else {
return this.get('store').findRecord('user', 'me').then(user => user.get('nodes'));
}
}
});


I actually have more in index.js route, but all I am trying to do is render my template in the directory
app/widgets/node_list.hbs
. I am confused as to where
renderTemplate
is actually supposed to be (what route), and the correct way to get my widget to show up in the index. Right now I am not getting any content to render, but the routes are showing in the ember inspector. I plan on adding several more widgets to the index, but I would like someone to help me understand the correct way to route and render these 'widget' templates into another template. Thanks in advance!

Answer

Well, this is the best I have found in regards to this:

// router.js:
import Ember from 'ember';
import config from './config/environment';

const Router = Ember.Router.extend({
    location: config.locationType
});

Router.map(function() {
    this.route('index', {
        path: '/'
    });
    this.route('nodes', function() {
        this.route('detail', {
            path: '/:node_id'
        }
    });
});

export default Router;

// app/routes/index.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

export default Ember.Route.extend(AuthenticatedRouteMixin, {
    store: Ember.inject.service(),
    session: Ember.inject.service(),
    model() {
        let user = this.modelFor('application');
        if (user) {
            return user.get('nodes'); // Fetch from `/users/me/nodes/`
        } else {
            return this.get('store').findRecord('user', 'me').then(user => user.get('nodes'));
        }
    },
    renderTemplate: function() {
        this.render();
        this.render('widgets/project_list', {
            into: 'index',
            outlet: 'node_list'
        });
    }
});

I am not using the models from my app/routes/nodes.js file this way and basically setting the models twice in my app this way. As far as I have found there is no way to get the models from node.js because they are not a parent of the index. So I have to set the model in the index in order for this to work. I also can't seem to access my nodes/index.js controller this way either if I use var controller = this.controllerFor('nodes/index');, then controller: controller in the renderTemplate() function. That means I have to move my actions to a separate controller (which is probably the right way to do it), in order to access them in my widget. But I want those same actions to be accessed for other routes, and I do not want duplicates throughout my app.

I think the best way to do this actually is to build my widgets as components instead of trying to make separate templates for each widget and then rendering them in the index template. I am going to attempt this instead.