Angularjs reusable Component with demo

angularjs reusable components angular 2 reusable components angular2 reusable components angular 4 reusable components angularjs components example angularjs components tutorial angularjs reuse html template how to create reusable directive in angularjs angularjs component vs directive

Angularjs 1.5 introduced component which can be used for reuseable component similar to user control in ASP.Net. We will create a component and see how we can use with different pages by just adding a single element. If we will try to creat the same as a directive then will be complicated but with component it will be very easy.

Advantages of Components:

  • simpler configuration than plain directives
  • promote sane defaults and best practices
  • optimized for component-based architecture
  • writing component directives will make it easier to upgrade to Angular

When not to use Components:

  • for directives that need to perform actions in compile and pre-link functions, because they aren't available
  • when you need advanced directive definition options like priority, terminal, multi-element
  • when you want a directive that is triggered by an attribute or CSS class, rather than an element

Reusable component:

Let's take an example of address component in angularjs, say we have diffrent pages like Costomer, Employee and Supplier, all the three pages have common part address, so if we can create a component called AddressComponent and used on all the three pages will reduce the condig efforts. Let's see it by writing the code, we have these properties in our address:

  • Street Address 1
  • Street Address 2
  • Country
  • State
  • City
  • ZipCode

Country, State and City will be drop down so we need to add code to fill it on every page but if we use component then only once.

As a common practive we use model in a service, so we can create a address view model in the service like this:

var addressViewModel = {
    street1: null,
    street2: null,
    city:null,
    country: null,
    state: null,
    zipcode: null
};

Now we need to create the view model for customer and it will have other properties like first name, last name, phone, fax etc.

service.customerViewModel = {
    firstName: null,
    lastName: null,
    address: addressViewModel,
    phone: null,
    fax:null
}

Note, we use here address view model for customer address. Now let's create our customer controller and define the model for it by using service say 'dataService'

app.controller('customerCtrl', function(dataService){
    var vm = this;
    vm.model = angular.copy(dataService.customerViewModel);
})

if you want to check the model properties add following code in our customer HTML page

<div ng-controller="customerCtrl as vm">
    <pre>{{vm.model | json}}</pre>
</div>

It will show all the properties in our model.

To create our address component create one html file say `address.component.html' and add following HTML in it:

<div class="row">
 <div class="col-md-6">
  <input type="text" class="form-control" ng-required="true"
         ng-model="ctrl.address.street1" 
         placeholder="Street Address 1"/>
 </div>
 <div class="col-md-6">
  <input type="text" class="form-control" ng-required="true"
         ng-model="ctrl.address.street2"
         placeholder="Street Address 2" />
 </div>
</div>
<div class="row">
 <div class="col-md-6">
  <select ng-model="ctrl.address.country"                
      ng-options="obj.id as obj.country for obj in ctrl.countries"
      ng-change="ctrl.getCountryStates()"
      class="form-control" 
      ng-required="true"
      id="country">
    <option value="">Choose Country</option>
  </select>
 </div>
 <div class="col-md-6">
  <select ng-model="ctrl.address.state"                
      ng-options="obj.id as obj.state for obj in ctrl.states"
      ng-change="ctrl.getStateCities()"
      class="form-control" 
      ng-required="true"
      id="country">
    <option value="">Choose State</option>
  </select>
 </div>
</div>
<div class="row">
 <div class="col-md-6">
  <select ng-model="ctrl.address.city"                
      ng-options="obj.id as obj.city for obj in ctrl.cities"
      class="form-control" 
      ng-required="true"
      id="country">
    <option value=""> Choose City</option>
  </select>
 </div>
 <div class="col-md-6">
  <input type="text" class="form-control"  ng-required="true"
        ng-model="ctrl.address.zipcode"
        placeholder="Zip Code" />
 </div>
</div>

There is nothing new, it is very simple code like other angular HTML pages, if you note, I use ctrl.address.property everywhere because I used controllerAs in my component, which we will see in our javascript code now, so let's create our address.component.js and add following code in it:

app.component('addressComponent', { templateUrl: 'address.component.html', controller: addressCtrl, controllerAs: 'ctrl', bindings:{ address: '=' } })

  • templateUrl: We provided templateUrl (html page path)
  • controller: name to handle code related to this component and not the other page, we will create next
  • controllerAs: we give a name because we are not using the scope here
  • bindings: = means both direction binding, data change in page controller will reflect in component and vise versa.

addressCtrl is a function which will handle the data related to component, like load countries, state and cities from service and on change we will relaoad the data related to country and state, so let's create this function:

function addressCtrl(dataService){
    var ctrl = this;
    ctrl.$onInit = function(){
     ctrl.countries = dataService.getCountry();
    }
    ctrl.getCountryStates = function(){
      ctrl.states = dataService.getCountryState(ctrl.address.country);
      ctrl.cities =[];
    }
    ctrl.getStateCities = function(){
       ctrl.cities = dataService.getStateCity(ctrl.address.state);
    }
}

All data related to country, state and city drop down are loading in our component only, next we will create different paged and use this component and we will see how easy for us to use this component and how much time saving.

Customer Page with address component:

Here is the complete code for Customer controller

app.controller('customerCtrl', function(dataService){
    var vm = this;
    vm.model = angular.copy(dataService.customerViewModel);    
    vm.save = function(){
      //code to save the data
    }    
    vm.clear = function(){
      vm.model = angular.copy(dataService.customerViewModel);
    }   
})

Note: there is nothing to load the countries, states or cities just we created model and two method to save and clear the data.

Let's copy the complete html for the customer page then we can see the detail and magic parts in it:

<div  ng-controller='customerCtrl as vm'>
  <fieldset>
    <legend>Customer </legend>
    <form name="vm.frmCustomer" novalidate>
         <div class="row">
           <div class="col-md-6">
              <input type="text" class="form-control"  ng-required="true" 
                   ng-model="vm.model.firstName" 
                   placeholder="First Name"/>
           </div>              
           <div class="col-md-6">
              <input type="text" class="form-control" ng-required="true" 
                   ng-model="vm.model.lastName" 
                   placeholder="Last Name"/>
           </div>
         </div>

         <address-component address="vm.model.address"></address-component>

         <div class="row">
           <div class="col-md-6">
              <input type="text" class="form-control"  ng-required="true" 
                   ng-model="vm.model.phone" 
                   placeholder="Customer Phone#"/>
           </div>              
           <div class="col-md-6">
              <input type="text" class="form-control" 
                   ng-model="vm.model.fax" 
                   placeholder="Customer Fax #"/>
           </div>
         </div>

         <div class="row">
           <div class="col-md-12">
             <button type="submit" ng-click="vm.save()" class="btn btn-primary" ng-disabled="vm.frmCustomer.$invalid">Save</button>
             <button type="button" ng-click="vm.clear()" class="btn btn-warning">Clear</button>
           </div>
         </div>
    </form>
   </fieldset>
</div>

Some properties like first name, last name, phone and fax are not in address so we added them here on the page but for address we use our address-component component and pass the address model to it:

<address-component address="vm.model.address"></address-component> 

Employee page with address component:

Say we want to create an employee page having following properties:

  • First Name
  • Last Name
  • Address
  • Date of Birth
  • Joining Date

Simply create a model similar to customer in service and use that, let's add

service.employeeViewModel = {
    firstName: null,
    lastName: null,
    address: addressViewModel,
    dob: null,
    joining: null
}

Create employee controller with following code:

app.controller("employeeCtrl", function(dataService){
    var vm = this;
    vm.model= angular.copy(dataService.employeeViewModel);
    vm.save = function(){
      // code to save employee
    }
    vm.clear = function(){
      vm.model= angular.copy(dataService.employeeViewModel);
    }       
})

Note the code, it is very less now, that's the best part of using the component, create once and keep using without any change. HTML of emplyee is very similar to customer so not sharing here, you can check on the plunker.

Supplier page with address component:

If we need to create one more page say Supplier which have the model like this:

service.supplierViewModel = {
    supplier: null,
    companyName: null,
    address: addressViewModel,
    phone: null,
    fax:null
}

See, we have some different properties from customer and employee but still we need the address so we can use our address component and pass the address model to update. What about the controller, it will be very similar, see this:

app.controller("supplierCtrl", function(dataService){
    var vm = this;
    vm.model= angular.copy(dataService.supplierViewModel);
    vm.save = function(){
      // code to save employee
    }
    vm.clear = function(){
      vm.model= angular.copy(dataService.supplierViewModel);
    }
})

Not sharing the html because nothing is new, please check the plunker.

Call parent function from component:

In some cases we need to call the parent page method from component, say we want to call the save method on page controller from component then we can pass the method with bindings like this:

<address-component 
   address="vm.model.address"
   savemethod = "save()">
</address-component>
// In bindings
bindings:{
      address: '='
  savemethod: '&'
}

In component controller call this method:

vm.saveComponent = function(){
    vm.savemethod(); // value we used in bindings
}
Ali Adravi Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
  • angularjs
  • component
By Ali Adravi On 23 Oct, 17  Viewed: 489

Other blogs you may like

Angularjs powerful paging on table and searching with delay and demo

Paging on table is the basic requirement and most of us look for some grid so it can provide the complete feature of paging and sorting but in Angularjs it is so easy that anyone can achieve it by writing some code. I checked and found most of the available code give the paging feature in for 1 to... By Ali Adravi   On 14 Aug 2015  Viewed: 10,099

Angularjs Cascading Dropdown/Select with demo

Cascading dropdown with angularjs is easier than MVC and ASP.Net. In Angularjs ng-change is the best event to hook the function to get the second dropdown list items. In this article, we will try to fill the state dropdown on selection change of country and then fill the city dropdown on change... By Ali Adravi   On 06 Aug 2015  Viewed: 39,381

Angularjs CRUD with Web API, Entity Framework & Bootstrap modal popup part 2

Add/Edid Customer in Modal Popup --- In previous article we discussed how to search, delete and show detail of customer and contact list. In this article we will try to open the modal popup to add new customer and edit an existing customer record. I divided article in two parts because of the... By Ali Adravi   On 29 Jul 2015  Viewed: 15,001

Custom Directives in AngularJS with example and demo

Angularjs custom directives are the common to avoid the duplicate code, it is easy powerful and really nice. There are already too many directive have been created by experts but as a developer we need to write our own to achieve our specific goal. ng-model, ng-if, ng-show, ng-repeat all these are... By Ali Adravi   On 29 Jul 2015  Viewed: 3,032

Angularjs CRUD with Web API, Entity Framework & Bootstrap modal popup part 1

Search sort Insert update and delete are the basic features we need to learn first to learn any language, In this article we will try to create these features with Web API, bootstrap modal popup and ui.router. We will use enetity framework code first to save and retrieve data from database. We... By Ali Adravi   On 28 Jul 2015  Viewed: 26,007