03.0.0 Edit a Model - bazzel/ember2-workshop GitHub Wiki
- Add behavior to the Edit button
- Change state of detail page
- Edit the product
- Make the buttons work
- Rollback changes on url change
- Bonus: Make use of the
hasDirtyAttributesstate
See the installation instructions. Use tag 3.0.0.
For the time being we stub all requests by using Mirage. This tag already updated frontend/app/mirage/config.js to stub the PATCH request when a model is updated.
- Open
frontend/app/templates/products/show.hbs. - Change the markup for the Edit button and call the (yet to define)
toggleEditingaction when you click it:
- In the app, select a product and click the Edit button.
- Inspect the error shown in the Console tab in the browser. Ember is missing the
toggleEditingaction, so let's create this. Ember first looks for this action on the ProductsShowController. Since we didn't need any special behavior for this controller until now, it's auto-generated. - In the terminal, enter
ember g controller products/show. - Open
frontend/app/controllers/products/show.jsand addtoggleEditing:
export default Ember.Controller.extend({
actions: {
toggleEditing() {
alert('Hello from toggleEditing');
}
}
});- In the app, select a product and click the Edit button again.
The action should change the isEditing state of the controller so the template can show the proper markup accordingly.
- Open
frontend/app/controllers/products/show.jsand update the code:
export default Ember.Controller.extend({
isEditing: false,
actions: {
toggleEditing() {
this.toggleProperty('isEditing');
}
}
});- In the app, select a product and click the Edit button again and use the Ember Inspector to see how the
isEditingproperty changes. - Open
frontend/app/templates/products/show.hbs. - Wrap the content for the page in a conditional:
- In the app, select a product and click the Edit button again. This sets
isEditingto true, which hides the product detail (notice that the template is still rendered, though). Selecting another product will not bring back the product detail; the controller's propertyisEditingis still true so the template still hides the details. - You'll reset the
isEditingwhen you change the URL. - Open
frontend/app/routes/products/show.jsand update the code:
export default Ember.Route.extend({
actions: {
willTransition() {
this.controller.set('isEditing', false);
}
}
});- In the app, select a product and click the Edit button again and then select a different product.
- Open
frontend/app/templates/products/show.hbs. - Scroll down to
{{/unless}}and add{{else}}and an empty line above it:
- Paste the code from
form.hbsin this gist onto the new line.
- Open
frontend/app/templates/products/show.hbs. - Change the markup for the Cancel button and call the
toggleEditingaction when you click it:
- Open
frontend/app/controllers/products/show.js. - Add code to rollback the changes:
toggleEditing() {
this.toggleProperty('isEditing');
this.model.rollbackAttributes();
}- Change the markup for form tag and call the yet to be defined
submitaction when it is submitted:
- In the app, edit a product and submit the form.
- Inspect the error shown in the Console tab in the browser. Ember is missing the
submitaction, so let's create this. - Open
frontend/app/controllers/products/show.jsand addtoggleEditing:
actions: {
toggleEditing() {
...
},
submit() {
this.model.save().then(() => {
this.set('isEditing', false);
});
}
}- In the app, edit a product and submit the form again.
When you make changes to a product and then change the url (e.g. click another product), the changes remain. Let's fix that.
- Open
frontend/app/routes/products/show.jsand update the code:
willTransition() {
var product = this.currentModel;
if (product.get('hasDirtyAttributes')) {
product.rollbackAttributes();
}
this.controller.set('isEditing', false);
}- Open
frontend/app/templates/products/show.hbs. - Bind the
classattribute of the submit button to the model'shasDirtyAttributesstate. When the model is dirty, add the classdisabledto the button. Regardless the model's state,updateis always used as className:
- Open
frontend/app/templates/products.hbs. - Update the div tag wrapped by
<div class='product'>as follows: