Ember.js - CRUD scripts - specifying a view from a route

I previously asked a question in which I wanted to bind the collection located in the controller to the list script view , however I added details and edited the templates and views in my structure, creating a couple of additional sub-items:

root.contacts.details -> /contacts/:contact_id
root.contacts.edit -> /contacts/:contact_id/edit

In my details scripts, I first started calling connectOutlets as follows

 [...] connectOutlets: function (router, contact) { router.get('contactController').set('contact', contact); router.get('applicationController').connectOutlet('contacts'); },[...] 

This will change the route in the browser navigation bar, but it will load the same view, then I changed the .connectOutlet contact to instead of contacts to the next

 [...] connectOutlets: function (router, contact) { router.get('contactController').set('contact', contact); router.get('applicationController').connectOutlet('contact'); },[...] 

Because of this, I had to create a new controller, because Ember could not find a controller named contactController , so I ended up with contactController and contactsController , and I think that I am violating the MVC of the template, as well as creating an additional class to support, possible problems with synchronization (when editing a contact, I would have to manually synchronize with the collection in contactsController ). Also, when I go to /#/contacts/2/edit , it loads the details view, since I use the same name in .connectOutlet('contact') . Therefore, what I do cannot be right. I do not want to create a controller for each scenario. I am sure that this is not so.

I also tried to set the view (in my case App.EditContactView ) instead of the resource name in connectOutlets , but I got an error "I can pass" the name or class of the view, but not both, but I was not going through viewClass and rather as an argument connectOutlet .

I also tried to set the view or an instance of my view to the route itself, and I would either break my JavaScript, or in some cases get an error stating that "App.EditContactView does not have a CharAt method."

And again I got a little lost. I saw other questions in SO and elsewhere, but only the ones I found used either the Gordon Hempton ember-routermanager routermanager (which seems good, but I'm only interested in using the built-in now), Ember.StateManager or not using the / state at all route. The documentation does not explain too much about these things.

Question What would be the ideal approach to solve all CRUD scenarios with Ember.Router ? I want my contactsController to list everything, find, edit, add one and delete one contact. Right now I have one contactsController with findAll and one contactController with find , edit , remove , add due to name problems.

Currently, I do not use ember data, so I'm more interested in examples without references to ember-data (now I am taking steps for children without any plug-ins).

Here is the current version of my router:

Js

 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(); 

Matching Templates

 <script type="text/x-handlebars" data-template-name="contact-details"> {{#if controller.isLoaded}} <img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="210" height="240" /><br /> <strong>{{contact.fullName}}</strong><br /> <strong>{{contact.alias}}</strong> {{else}} <img src="images/l.gif" alt="" /> Loading... {{/if}} </script> <script type="text/x-handlebars" data-template-name="contact-edit"> <strong>Edit contact</strong><br /> First Name: <input type="text" id="txtFirstName" {{bindAttr value="contact.firstName"}}<br /> Lasst Name: <input type="text" id="txtLastName" {{bindAttr value="contact.lastName"}}<br /> Email: <input type="text" id="txtEmail" {{bindAttr value="contact.email"}}<br /> </script> <script type="text/x-handlebars" data-template-name="contact-table-row"> <tr> <td> <img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="50" height="50" /><br />{{contact.fullName}} </td> <td> Twitter: {{#if contact.twitter}}<a {{bindAttr href="contact.twitter"}} target='_blank'>Follow on Twitter</a>{{else}}-{{/if}}<br /> </td> <td> <a href="#" {{action contactDetails context="contact"}}>Details</a> | <a href="#" {{action contactEdit context="contact"}}>Edit</a> </td> </tr> </script> 

Note If something is unclear, ask in the comments section and I can edit it with more details.

Change I added this project to GitHub even in the place that I would like to present as a training example. The goal is to move forward and create a CRUD template in the near future. Currently using the MS Web API, but may soon add a version of Rails.

+7
source share
1 answer

Something happens here, I will try to answer them, but if I miss something, do not hesitate to leave a comment. You seem to be inventing a lot of the things that Ember is already doing for you.

First, if you want to pass the view to the connectOutlet method, you need to pass the hash as the only argument.

 router.get('applicationController').connectOutlet({ viewClass: App.EditContactView, controller: router.get('contactsController'), context: context }) 

Secondly, the lack of two contact controllers is not embarrassing, in fact I would recommend it. The singular ContactController that inherits from the ObjectController and the ContactsController that inherits from the ArrayController , which means you can easily use the built-in proxy content.

Third, if you add the find and findAll class methods to your models, you will make life a lot easier for yourself.

  • You do not need to define the serialization / deserialization methods that you have defined, by default Ember will search for the model with the name that is displayed from the route, like this: contact_id will automatically look for App.Contact.find (:. contact_id)

  • You can also change your connectOutlets index to: router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())

One more tip, at the moment your data and editing routes are almost completely identical. I would create one route called company , and then create child parts and edit them inside.

+9
source

All Articles