After creating and reading data, CRUD tells us that updating is the next step. You have an edit route for a sighting, but you need to put it to use by updating the sighting listing with a button to navigate to the edit route. You also need to add a form with sighting fields to the edit template; have the edit route’s model retrieve witnesses, cryptids, and the sighting; and add route parameters to the edit route object in app/router.js. Finally, you need to create a controller to add actions for the edit form.
Let’s start with adding an Edit button in app/templates/sightings/index.hbs. To give more context to the list, add the name and image of the cryptid that was sighted as well.
... <div class="media well"> <img class="media-object thumbnail" src="{{if sighting.cryptid.profileImg sighting.cryptid.profileImg 'assets/images/cryptids/blank_th.png'}}" alt="{{sighting.cryptid.name}}" width="100%" height="100%"> <div class="caption"> <h3>{{sighting.cryptid.name}}</h3> {{#if sighting.location}} <h3>{{sighting.location}}</h3> <p>{{moment-from sighting.sightedAt}}</p> {{else}} <h3 class="text-danger">Bogus Sighting</h3> {{/if}} </div> {{#link-to 'sighting.edit' sighting.id tagName="button" class="btn btn-success btn-block"}} Edit {{/link-to}} </div> ...
Load http://localhost:4200/sightings and check out your new Edit button (Figure 24.4).
Now add the dynamic parameters to the edit route in router.js.
... this.route('sighting', function() { this.route('edit', {path: "sightings/:sighting_id/edit"}); }); ...
Add the retrieval methods for sightings, cryptids, and witnesses to the route in app/routes/sighting/edit.js:
... export default Ember.Route.extend({ model(params) { return Ember.RSVP.hash({ sighting: this.store.findRecord('sighting', params.sighting_id), cryptids: this.store.findAll('cryptid'), witnesses: this.store.findAll('witness') }); } });
Next, add the form elements to app/templates/sighting/edit.hbs, as you did when creating a new sighting.
{{outlet}}<h1>Edit Sighting: <small> {{model.sighting.location}} - {{moment-from model.sightin.sightedAt}} </small> </h1> <form {{action "update" model on="submit"}}> <div class="form-group"> <label for="name">Cryptid</label> {{input value=model.sighting.cryptid.name type="text" class="form-control" name="location" disabled=true}} </div> <div class="form-group"> <label>Witnesses</label> {{#each model.sighting.witnesses as |witness|}} {{input value=witness.fullName type="text" class="form-control" name="location" disabled=true}} {{/each}} </div> <div class="form-group"> <label for="location">Location</label> {{input value=model.sighting.location type="text" class="form-control" name="location" required=true}} </div> <button type="submit" class="btn btn-info btn-block">Update</button> <button {{action 'cancel'}} class="btn btn-block">Cancel</button> </form>
You are almost there; the controller is the final step.
You need to set the form {{action}}
to
update
. Also, because Tracker is only going to allow location changes at this point,
you will render the cryptid and witnesses in
disabled input fields.
Create the controller:
ember g controller sighting/edit
Open app/controllers/sighting/edit.js and add the update
and cancel
actions:
import Ember from 'ember'; export default Ember.Controller.extend({ sighting: Ember.computed.alias('model.sighting'), actions: { update() { if(this.get('sighting').get('hasDirtyAttributes')){ this.get('sighting').save().then(() => { this.transitionToRoute('sightings'); }); } }, cancel() { if(this.get('sighting').get('hasDirtyAttributes')){ this.get('sighting').rollbackAttributes(); } this.transitionToRoute('sightings'); } } });
Similar to creating model records, updating is as easy as calling
save. You only want to call the API when your
record has changed, hence
sighting.get('hasDirtyAttributes')
. Ember has
thought of it all!
Notice the use of Ember.computed.alias
. This
is a computed property assigned so you do not have to type as much when
calling on the active sighting
. You can alias any property
to get quick access, especially if the properties are nested.
18.221.123.73