Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Note: Apologies for the lengthy answer, but I thought it would be good to elaborate, since this is quite a common use case and this should be helpful to anyone new to Ember (and Ember Data).</p> <p>In my opinion the following would be the best way to implement your scenario in Ember and Ember Data:</p> <p>Set up your templates for the <code>application</code> (everything else will be rendered into this routes's <code>{{outlet}}</code>), <code>groups</code> (this template will wrap everything to do with groups), <code>groups/index</code> (to display a list of all groups) and <code>group</code> (to display one group).</p> <pre><code>&lt;script type="text/x-handlebars" data-template-name="application"&gt; &lt;h1&gt; ember - latest jsfiddle &lt;/h1&gt; {{outlet}} &lt;/script&gt; &lt;script type="text/x-handlebars" data-template-name="groups"&gt; {{outlet}} &lt;/script&gt; &lt;script type="text/x-handlebars" data-template-name="groups/index"&gt; &lt;h2&gt; Groups &lt;/h2&gt; {{#each group in content }} &lt;div class="buttonlink"&gt; {{#link-to "group" group}}{{group.name}}{{/link-to}}&lt;/div&gt; &lt;/div &gt; {{/each}} &lt;/script&gt; &lt;script type="text/x-handlebars" data-template-name="group"&gt; &lt;h2&gt;{{name}} Items&lt;/h2&gt; {{#each item in items}} &lt;div class="buttonlink"&gt; {{item.name}}&lt;/div&gt; &lt;/div &gt; {{/each}} &lt;br /&gt; {{#link-to "groups.index"}}Back to groups{{/link-to}} &lt;/script&gt; </code></pre> <p>In your JS you then set up your store. For testing I used the <code>DS.FixturesAdapter</code>, which lets me specify data directly in my JS for testing purposes. Eventually you will want to replace this with something like <code>DS.RESTAdapter</code> to talk to your backend.</p> <pre><code>App = Ember.Application.create({}); App.Store = DS.Store.extend({ revision: 13, adapter: DS.FixtureAdapter }); </code></pre> <p>We then specify our models using Ember Data:</p> <pre><code>App.Group = DS.Model.extend({ name: DS.attr('string'), items: DS.hasMany('item', { async: true }), }); App.Item = DS.Model.extend({ name: DS.attr('string'), group: DS.belongsTo('group'), }); </code></pre> <p>I omitted the fixtures data for brevity's sake, but you can see it in the jsFiddle below. The <code>{ async: true }</code> tells Ember Data that the parent (App.Group) and child (App.Item) models are asynchronously loaded (i.e. not necessarily at the same time). </p> <p>As a next step we define which routes we have in our application. For this example we only care about groups - specifically looking all groups and at individual ones. </p> <pre><code>App.Router.map(function() { this.resource('groups', function() { this.resource('group', { path: '/group/:group_id' }); }); }); </code></pre> <p>Now all that remains to be done is to tell Ember what to do when each route is entered:</p> <pre><code>App.IndexRoute = Ember.Route.extend({ redirect: function() { this.transitionTo('groups.index'); } }); </code></pre> <p>The <code>App.Index</code> route is the default route of the application (think of it as the 'home' route). In our case we want to go directly to a list of groups, so we redirect to <code>groups.index</code>. </p> <pre><code>App.GroupsIndexRoute = Ember.Route.extend({ model: function() { return this.get('store').findAll('group'); } }); </code></pre> <p>This sets the model of the route to all groups that we have in our store. Ember will automatically detect that this is an array and create a corresponding <code>Ember.ArrayController</code> that we can use in that route - but we could also override it if we wanted to add additional functionality. </p> <p>Note that we do not need to explicitly set up an <code>App.GroupRoute</code> or <code>App.GroupIndexRoute</code> since Ember is smart enough to do that for us in the background (however, again, we could override it if we needed to).</p> <p>See <a href="http://jsfiddle.net/kFkBB/7/" rel="nofollow">this jsFiddle</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload