1
votes

Note: I imagine that this will be a super easy question for anyone with Ember experience. Don't be daunted by the length of my question. Skip down to the bottom if you don't want to read all of the overhead.

Overhead

My company has a project coming up which requires the use of front-end technologies to accomplish what I would otherwise prefer to do with PHP.

We looked into a few different JavaScript frameworks, and the solution that we agreed upon was Ember.js.

I followed the TodoMVC tutorial on their website, and learned the very basics.

With this project, we will be using an AJAX request to pull in our data at the start of the application, and then put everything into fixtures.

I'm having difficulty figuring out how to pass multiple fixtures into my template at the same time. I started with adding two fixtures. Here are their data and definitions:

App.Students = DS.Model.extend({
    first: DS.attr('string'),
    last: DS.attr('string'),
    classes: DS.hasMany('ClassGroup')
});

App.ClassGroup = DS.Model.extend({
    className: DS.attr('string'),
    isActive: DS.attr('number'),
    students: DS.hasMany('Students',{ async: true })
});

App.ClassGroup.FIXTURES = [
    {
        id: 1,
        className: 'Class 1',
        isActive: 1,
        students: [1, 2]
    },
    {
        id: 2,
        className: 'Class 2',
        isActive: 0,
        students: [2]
    }
];

App.Students.FIXTURES = [
    {
        id: 1,
        first: 'Student',
        last: 'One',
        classes: [1]
    },
    {
        id: 2,
        first: 'Student',
        last: 'Two',
        classes: [1, 2]
    }
];

This is just a very simple implementation. The actual data will have dozens of relations, but I've simplified things for the purpose of learning this framework.

Here is how I am currently setting up my router:

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return this.store.find('ClassGroup');
    }
});

Doing it this way allows me to access the data via Handlebars by using {{#each model}} and then something like {{className}} to access it's data members. I am also able to jump to the students array by nesting another each statement like {{#each students}}.

However, I cannot figure out how to get more than one entry point into my data. For example, by passing ClassGroup via the router, I am unable to access the Students fixture by itself; I must first loop through ClassGroup, and from there, access a student.

Likewise, if I change my router to pass in the students fixture, I can loop through the students, and then jump to the classes via a nested each statement, but I lose the ability to simply loop through a list of all classes.

Is there a way that I can pass all of my fixtures into the template? Am I going about this the right way?

The Long Story Short

How can I pass ALL of my fixtures into the template at once, in such a way that I can access my students array or my classes array? How can I access said fixture data (i.e., if I want to display the first name of the student with ID 2, represented as students[2]['first'] in a language like PHP, how can this be done with handlebars)?

1

1 Answers

1
votes

That's right, the Template only has access to what it's been passed by the Controller. In this case, since you don't explicitly set up the controller, and the model is an array, it'll be an array controller, hence you ability to do {{#each}} to iterate over the ClassGroups (you actually don't even need model). You haven't passed in the students array anywhere explicitly, nor created it in the controller, so you don't have access to it in the template. Fortunately, Ember has a setupController route hook which does exactly this kind of thing. In your example:

App.IndexRoute = Ember.Route.extend({
    model: function() {
        return this.store.find('ClassGroup');
    },
    setupController: function(controller, model){
        this._super(controller, model);
        controller.set('students', this.store.find('Students'));
    }
});

Now you'll have a students property available on your controller and therefore your template.