Note that there are some explanatory texts on larger screens.

plurals
  1. POEmber.js - CRUD scenarios - Specifying View from within a Route
    primarykey
    data
    text
    <p>I've asked a question previously in which I wanted to <a href="https://stackoverflow.com/questions/11301798/ember-js-how-to-properly-bind-a-collection-to-a-view-using-ember-router">bind a collection residing in the controller to the list scenario view</a>, however, I've added <em>details</em> and <em>edit</em> templates and views to my structure producing a couple of extra sub-routes:</p> <p><code>root.contacts.details -&gt; /contacts/:contact_id</code><br> <code>root.contacts.edit -&gt; /contacts/:contact_id/edit</code></p> <p>In my <code>details</code> scenarios I first started calling the <code>connectOutlets</code> as follows</p> <pre><code>[...] connectOutlets: function (router, contact) { router.get('contactController').set('contact', contact); router.get('applicationController').connectOutlet('contacts'); },[...] </code></pre> <p>This would change the route in the browser navigation bar, but it would load the same view, then I changed the <code>.connectOutlet</code> to <strong><em>contact</em> instead of <em>contacts</em></strong> to the following</p> <pre><code>[...] connectOutlets: function (router, contact) { router.get('contactController').set('contact', contact); router.get('applicationController').connectOutlet('contact'); },[...] </code></pre> <p>Because of this, I had to create a new controller as Ember couldn't find a controller named <code>contactController</code>, so I ended up with a <code>contactController</code> and a <code>contactsController</code> and I think I'm breaking the MVC pattern doing this, as well as creating an extra class to maintain, possible problems with syncronization (when editing a contact I'd have to manually sync with the collection in the <code>contactsController</code>). Also when I navigate to <code>/#/contacts/2/edit</code> it loads the details view since I'm using the same name in <code>.connectOutlet('contact')</code>. So what I'm doing can't be right. I don't want to create controller per scenario. I'm sure this is not how it's done.</p> <p>I also tried setting the view (in my case <code>App.EditContactView</code>) instead of the resource name in the <code>connectOutlets</code> but I got an error saying I can pass "<em>a name or a viewClass but not both</em>" but I was not passing through <code>viewClass</code> and rather as an argument of <code>connectOutlet</code>. </p> <p>I have also tried to set a view or an instance of my view to the route itself and I would either break my JavaScript or in some cases I'd get an error saying that "<em>App.EditContactView does not have a method CharAt</em>". </p> <p>Then again, I got a little lost. I have seen other questions at SO and else where but the ones I've found were either using <a href="https://github.com/ghempton/ember-routemanager" rel="nofollow noreferrer"><code>ember-routermanager</code></a> by Gordon Hempton (which seems good, but I'm interested in using built-in only right now), <code>Ember.StateManager</code> or not using state/route at all. Documentation isn't explaining too much about these things yet.</p> <p><strong>Question</strong>: What would be the ideal approach to deal with all CRUD scenarios with <code>Ember.Router</code>? I want my <code>contactsController</code> to be able to list all, find one, edit one, add one and delete one contact. Right now I have one <code>contactsController</code> with <code>findAll</code> and one <code>contactController</code> with <code>find</code>, <code>edit</code>, <code>remove</code>, <code>add</code> because of naming problems.</p> <p>I am currently not using ember-data so I would be more interested in examples without references to ember-data (I am doing the baby steps without any plug-in for now).</p> <p>Here's the current version of my router:</p> <p><strong>JS</strong></p> <pre><code>App.Router = Ember.Router.extend({ enableLogging: true, location: 'hash', root: Ember.Route.extend({ // EVENTS gotoHome: Ember.Route.transitionTo('home'), gotoContacts: Ember.Route.transitionTo('contacts.index'), // STATES home: Ember.Route.extend({ route: '/', connectOutlets: function (router, context) { router.get('applicationController').connectOutlet('home'); } }), contacts: Ember.Route.extend({ route: '/contacts', index: Ember.Route.extend({ route: '/', contactDetails: function (router, context) { var contact = context.context; router.transitionTo('details', contact); }, contactEdit: function (router, context) { var contact = context.context; router.transitionTo('edit', contact); }, connectOutlets: function (router, context) { router.get('contactsController').findAll(); router.get('applicationController').connectOutlet('contacts', router.get('contactsController').content); } }), details: Ember.Route.extend({ route: '/:contact_id', view: App.ContactView, connectOutlets: function (router, contact) { router.get('contactController').set('contact', contact); router.get('applicationController').connectOutlet('contact'); }, serialize: function (router, contact) { return { "contact_id": contact.get('id') } }, deserialize: function (router, params) { return router.get('contactController').find(params["contact_id"]); } }), edit: Ember.Route.extend({ route: '/:contact_id/edit', viewClass: App.EditContactView, connectOutlets: function (router, contact) { router.get('contactController').set('contact', contact); router.get('applicationController').connectOutlet('contact'); }, serialize: function (router, contact) { return { "contact_id": contact.get('id') } }, deserialize: function (router, params) { return router.get('contactController').find(params["contact_id"]); } }) }) }) }); App.initialize(); </code></pre> <p><strong>Relevant templates</strong></p> <pre><code>&lt;script type="text/x-handlebars" data-template-name="contact-details"&gt; {{#if controller.isLoaded}} &lt;img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="210" height="240" /&gt;&lt;br /&gt; &lt;strong&gt;{{contact.fullName}}&lt;/strong&gt;&lt;br /&gt; &lt;strong&gt;{{contact.alias}}&lt;/strong&gt; {{else}} &lt;img src="images/l.gif" alt="" /&gt; Loading... {{/if}} &lt;/script&gt; &lt;script type="text/x-handlebars" data-template-name="contact-edit"&gt; &lt;strong&gt;Edit contact&lt;/strong&gt;&lt;br /&gt; First Name: &lt;input type="text" id="txtFirstName" {{bindAttr value="contact.firstName"}}&lt;br /&gt; Lasst Name: &lt;input type="text" id="txtLastName" {{bindAttr value="contact.lastName"}}&lt;br /&gt; Email: &lt;input type="text" id="txtEmail" {{bindAttr value="contact.email"}}&lt;br /&gt; &lt;/script&gt; &lt;script type="text/x-handlebars" data-template-name="contact-table-row"&gt; &lt;tr&gt; &lt;td&gt; &lt;img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="50" height="50" /&gt;&lt;br /&gt;{{contact.fullName}} &lt;/td&gt; &lt;td&gt; Twitter: {{#if contact.twitter}}&lt;a {{bindAttr href="contact.twitter"}} target='_blank'&gt;Follow on Twitter&lt;/a&gt;{{else}}-{{/if}}&lt;br /&gt; &lt;/td&gt; &lt;td&gt; &lt;a href="#" {{action contactDetails context="contact"}}&gt;Details&lt;/a&gt; | &lt;a href="#" {{action contactEdit context="contact"}}&gt;Edit&lt;/a&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/script&gt; </code></pre> <p><strong>Note</strong>: If there's anything unclear, please ask in the comment section and I can edit this with more details</p> <p><strong>Edit</strong>: I've added this project to <a href="https://github.com/MilkyWayJoe/hello-ember-router" rel="nofollow noreferrer">GitHub</a> even tho it's nowhere near what I'd like to expose as a learning sample. The goal is to progress on top of this and create a CRUD template in a near future. Currently using MS Web API, but might add a Rails version soon.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

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