I am making a toy libraries-tracking app using Ember. I am refactoring some code and this sendAction came up. What is the high level purpose of sendAction? Does it lead to cleaner code? I read this already.
Sorry if Ember questions have a lot of requisite code to read. I think these are the relevant files here.
Quick note, I have a libraries.new route which loads the routes/libraries/new.js file which has a renderTemplate method which renders a form template (this form template is used in a few different areas so this DRYs up my code). Since my route handler has a renderTemplate function that renders libraries/form, this is my libraries/form template:
<h2>{{title}}</h2>
<div class="row">
<div class="col-md-6">
{{library-item-form item=model buttonLabel=buttonLabel action='saveLibrary'}}
</div>
<div class="col-md-4">
{{#library-item item=model}}
<br/>
{{/library-item}}
</div>
</div>
Questions:
- The library-item-form component line has an action (what is this called? Is it a property?) property that gets passed the 'saveLibrary' action from its context (the libraries/new route handler right?)
- Since that is the passed in action for the component, that's the action that gets called when the buttonClicked method gets called in the library-item-form component because the buttonClicked method calls sendAction?
This is my library-item-form component js file:
import Ember from 'ember';
export default Ember.Component.extend({
buttonLabel: 'Save',
actions: {
buttonClicked(param) {
this.sendAction('action', param);
}
}
});
Here is my component template for library-item-form.hbs. It's a 3 input field form with a submit button. The submit button has an action called buttonClicked.:
<div class="form-horizontal">
<div class="form-group has-feedback {{if item.isValid 'has-success'}}">
<label class="col-sm-2 control-label">Name*</label>
<div class="col-sm-10">
{{input type="text" value=item.name class="form-control" placeholder="The name of the Library"}}
{{#if item.isValid}}<span class="glyphicon glyphicon-ok form-control-feedback"></span>{{/if}}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Address</label>
<div class="col-sm-10">
{{input type="text" value=item.address class="form-control" placeholder="The address of the Library"}}
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Phone</label>
<div class="col-sm-10">
{{input type="text" value=item.phone class="form-control" placeholder="The phone number of the Library"}}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" {{action 'buttonClicked' item}} disabled="{{unless item.isValid 'disabled'}}">{{buttonLabel}}</button>
</div>
</div>
</div>
Oh lastly, this is the libraries/new route handler with the saveLibrary action:
import Ember from 'ember';
export default Ember.Route.extend({
model: function () {
return this.store.createRecord('library');
},
setupController: function (controller, model) {
this._super(controller, model);
controller.set('title', 'Create a new library');
controller.set('buttonLabel', 'Create');
},
renderTemplate() {
this.render('libraries/form');
},
actions: {
saveLibrary(newLibrary) {
newLibrary.save().then(() => this.transitionTo('libraries'));
},
willTransition() {
let model = this.controller.get('model');
if (model.get('isNew')) {
model.destroyRecord();
}
}
}
});
Last questions
So it right to say that whatever action gets passed into the component in the action property (saveLibrary) is the action that gets called when the component's js file (components/library-item-form.js) calls an action (buttonClicked) that calls the sendAction function?
Does the first argument of sendAction HAVE to be called 'action'? Does the property in the line that invokes the component have to be called 'action?