Mapping component actions to the rest of your application

Till now, we have been successful in creating self-contained reusable components. These components render themselves and handle actions that can be served in isolation, irrespective of where the components are being used.

As we learned earlier in the chapter, events that are raised from the component's template are looked up in the component's action object. These events don't bubble up to the application's controllers or routes.

This all works fine till the components need to inform the rest of the application to take some business decisions. Ember.js framework lets your components translate the component events into meaningful application actions by using the sendAction method, accessible by the component.

Let's see that by an example. Let us create a date-picker component that is reusable across our application. But we would also want to invoke the context application specific method that is invoked when the user focuses out of the date picker.

Let's create the date picker template date-picker.hbs in the app/templates/components/ directory. This template will be a simple one with only the following contents:

<input type="date" name="date" {{action "submit" on="focusOut"}}>

The date-picker template is present at chapter-7/example1/app/templates/components/date-picker.hbs

As you can see, it's a simple input field of type date, and triggers the submit event on the component, when the user focuses out of the date-picker.

Now, let's use this component inside our index template:

<div>Please set the product's manufactoring date : {{date-picker action="saveMaufactoringDate"}}</div>
<br>
<div>Please set the product's expiry date : {{date-picker action="saveExpiryDate"}}</div>
<br>
<div>The Manufactoring Date Set By You is {{manufactoringDate}}</div>
<div>The Expiry Date Set By You is {{expiryDate}}</div>

Date-picker component being used in index template is present at chapter7/example1/app/templates/index.hbs

As you can see, we are using the same component at multiple places; the only difference is that we pass in different action names each time we use the component. This action tells the component the name of the controller or route action that should be manually triggered when the component is used. In order for the component to send the action to respective controller or route, we need to define the behavior in our component class. So, let's create date-picker.js in app/components/ directory:

import Ember from 'ember';

export default Ember.Component.extend({
  actions:{
    submit: function(){
      var date = this.$("input").val();
      this.sendAction('action',date);
    }
  }
});

The content of date-picker.js component is present at chapter-7/example1/app/components/ directory

As you can see, that component has a submit action defined inside the actions object; the submit action is triggered when the user focuses out of the date-picker. Inside the submit action we get the value of the input box, and call the sendAction method:

var date = this.$("input").val();
this.sendAction('action',date);

In the sendAction method, we pass in the name of the property that provides the name of the action that should be called on the controller or route, followed by the argument that should be supplied to the action, as follows:

{{date-picker action="saveMaufactoringDate"}}

So, in the preceding case, when we call this.sendAction('action',date), the saveMaufactoringDate event is looked up first in the respective controller and then in the route hierarchy.

So, in order to save the manufacturing date, we will have to handle the saveMaufactoringDate action in the index controller actions object. Till now, we were using the default controller that is auto-generated by the framework, but now, as we need to handle the action in the controller, we will have to define it in our application.

Let's create index.js in app/controller/ directory to define our controller. The index controller should handle both of saveMaufactoringDate and saveExpiryDate:

import Ember from "ember";
export default Ember.ObjectController.extend({
  manufactoringDate: "",
  expiryDate:"",
  actions: {
    saveMaufactoringDate: function(date){
      this.set("manufactoringDate",date);
    },
    saveExpiryDate: function(date){
      this.set("expiryDate",date);
    }
  }
});

The index controller is present at chapter-7/example1/app/controllers/index.js

So now, when we select the date in the date-picker, the respective property will be set on the controller. If you run the example1 application under chapter-7, and then navigate to http://localhost:4200/, you will see the following contents:

Mapping component actions to the rest of your application

The date-picker component in use in the index template

Now that we have used the sendAction method to notify the controller about the action from the component, let's discuss some other variations of the sendAction method.

When we used the sendAction method from our app/components/date-picker.js, we used this.sendAction('action',date). This would bubble up the event saveManufactoringDate or saveExpiryDate with the method argument, as date to the application. This is the same event that we assigned to the action property when using the component in our templates:

{{date-picker action="saveMaufactoringDate"}}
{{date-picker action="saveExpiryDate"}}

If we don't have arguments to be bubbled up to the controller or the route hierarchy, then we can also call this.sendAction(). Calling this.sendAction() would automatically extract the event name from the action property of the component, and bubble up the event to the respective controller or route hierarchy.

On the other hand, if we want to send multiple events to our controllers based on some action on the component, we can define the events while using the components as follows:

{{date-picker action1="someControllerAction1" action2=" someControllerAction2"}}

And then, we can use this.sendAction('action1',date) and this.sendAction('action2',date) from our component.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.97.53