« Back to Blogs

Reusable component with EmberJS

What is a Component?

Before we understand how to create a component, let’s have a look at what is component?

  • Ember Component is an encapsulated and reusable thing, which is wired up handlebar and javascript. Encapsulated and reusable, means it is by default protected from the outside world(CSS and Javascript can’t leak in or out.), After constructing a component you can use it on more than one place in your project.

Why you should use Component?

I assume at this moment you have a basic understanding of what a component is, but still you need to have an understanding that why you should use it in your project?

  • Component solves the problem of redundancy and can able to achieve abstraction in front-end development.
  • Let’s understand it by example.
    • Imagine you have user-profile widget. You want to display it on the sidebar of your application, in the main content, on change password page of your application.
    • Here, if you are writing code without component you should write those code at every place(on the sidebar, main content, change password page). You can abstract it by writing this code in a single component.

      We can handle this situation by using components which makes your work easy for the same.           That’s why we should use the component on your project.

Defining a Component

Let’s start on how we can define a component in ember project.

  • You can use Ember-CLI to create a component on your ember project.
    $ ember g component component-name
    • Component must have at least one dash on its name.
  • Let’s understand it with an example.
    • Create a component with name profile-card.
      $ ember g component profile-card
    • It will generate .hbs and .js file for single component.
    • Sample component be like this:
      app/templates/components/profile-card.hbs 
      <div class=”profile-card”>
        {{“it’s a profile-card component”}}
      </div>
    • Now we can use this component in our application.
      app/templates/index.hbs
      {{profile-card}}

Defining a Component at run-time

As per above syntax {{profile-card}} ({{component-name}}) render only same component at every time. While you want to add component at run-time you should go through {{component}} helper, that is allow you to choose component dynamically.

app/templates/index.hbs
{{!-- here we can use component-name dynamically. --}}
{{component component-name}}

When a parameter is passed to null or undefined to the component helper, the helper does not render anything.

Overview for lifecycle hook

  • For component render, re-render, remove Ember provide lifecycle hook that allows you to run those hook at a specific time in the life cycle of components. You can take a look for the same from here.

        Wait…. Wait… I have a question, We can achieve reusability by “Partial” in Ember, So why should we use a particular component?

  • Well... I have an answer, you can pass data to a component at render time, you can’t do it in “Partial”. Let's have a Look on it.

Pass properties in a component.

Component provides sync binding for changing in the property. Here we are going to simplify this by example.  

Passing property to the component:

  • Imagine you have a profile-card component, that is used to display a profile of the user.
    app/templates/components/profile-card.hbs
    <div class=”profile-card”>
     {{title}}
    </div>
  • Now you have a template where you want to use a profile-card component with the profile-card title.
    app/templates/index.hbs
    {{profile-card title=”profile-card”}}

Profile-card component will render in an index.hbs file with a title as profile-card. This property sync with template and component template, that means if componentProperty (title change in component), outerProperty(title of index.hbs) will be updated by reflecting the changes.

  Passing code-block to the component:

app/templates/components/profile-card.hbs
{{yield}}
  • Imagine you wants to pass code block to the component as specified below.
    app/templates/index.hbs
    {{#profile-card title="title"}}
    <form>
      <input name="profile"/>
    </form>
    {{/profile-card}}

    Here, you can reuse component with passing block, it will display in component by {{yield}}.

Handle Action in component

Component has property “action” in which we can define function which needs to be invoked by user activity. Let’s take an example of the same. Imagine we have a user form in profile-card component and we have to perform some action by clicking on the button.

app/templates/components/profile-card.hbs
<form {{action "performAction" on="submit"}}>
  User Name: <input type=”text” id="profile_name"/>
  <input type="submit"/>
</form>
app/components/profile-card.js
import Component from '@ember/component';
export default Component.extend({
actions: {
  performAction: function() {
    console.log($("profile_name").val());
   }
  }
});
  • When you click on submit button, action will be handled by performAction from actions property of a component.

  Passing action to the component:

Component also allows you to pass actions while component renders in a template. Basically a component is a combination of handlerBar and javascript. Action fires from handlebars which is handled on javascript(extended component class) file. You can pass this action from outer template as well by passing an action to the component.

app/templates/application.hbs
{{profile-card trigger=(action "triggerEvent")}}
app/controller/application.js
import Controller from '@ember/controller';
export default Controller.extend(
actions: {
 triggerEvent(profileName) {
   console.log(“event passed successfully”);
   console.log(“profile name is : ” + profileName);
  }
 }
});
  • Component ‘s handlebar contains a form for which action will be handled from component’s js(extended component class).
    app/templates/components/profile-card.hbs
    <form>
      <input name="profile"/>
      <button {{action "handleProfile"}}>Toggle</button>
    </form>
    app/component/profile-card.js 
    import Component from '@ember/component';
    export default Component.extend({
    actions: {
      handleProfile: function() {
        this.trigger($("#profile").val());
      }
     }
    });
  • Here component’s actions block can serve outer actions which will be passed at definition time as per above the example. Component's handleProfile action can be handled by outer event triggerEvent.

Conclusion

There are no reasons to not use a component in your ember application development. It can provide reusability and better interactivity in the code. I hope this will be helpful to you.

 

Comments
No comments yet. Be the first.
contact-us Request a callback