Angular 2 - Attribute Directives



Description

The attribute directive changes the appearance or behavior of a DOM element. These directives look like regular HTML attributes in templates. The ngModel directive which is used for two-way is an example of an attribute directive. Some of the other attribute directives are listed below:

  • NgSwitch: It is used whenever you want to display an element tree consisting of many children. The Angular places only selected element tree into the DOM based on some condition.

  • NgStyle: Based on the component state, dynamic styles can be set by using NgStyle. Many inline styles can be set simultaneously by binding to NgStyle.

  • NgClass: It controls the appearance of elements by adding and removing CSS classes dynamically.

Example

The below example describes use of attribute directives in the Angular 2:

<html>
  <head>
    <title>Contact Form</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.6/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/tools/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.6/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.6/angular2.dev.js"></script>
    <script>
      System.config({
        transpiler: 'typescript',
        typescriptOptions: { emitDecoratorMetadata: true },
        packages: {'app': {defaultExtension: 'ts'}},
        map: { 'app': './angular2/src/app' }
      });
      System.import('app/attribute_main')
            .then(null, console.error.bind(console));
    </script>

  </head>
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

The above code includes the following configuration options:

  • You can configure the index.html file using typescript version. The SystemJS transpile the TypeScript to JavaScript before running the application by using the transpiler option.

  • If you do not transpile to JavaScript before running the application, you could see the compiler warnings and errors which are hidden in the browser.

  • The TypeScript generates metadata for each and every class of the code when the emitDecoratorMetadata option is set. If you don't specify this option, large amount of unused metadata will be generated which affects the file size and impact on the application runtime.

  • Angular 2 includes the packages form the app folder where files will have the .ts extension.

  • Next it will load the main component file from the app folder. If there is no main component file found, then it will display the error in the console.

  • When Angular calls the bootstrap function in main.ts, it reads the Component metadata, finds the 'app' selector, locates an element tag named app, and loads the application between those tags.

To run the code, you need the following TypeScript(.ts) files which you need to save under the app folder.

attribute_main.ts
import {bootstrap} from 'angular2/platform/browser';       //importing bootstrap function
import {AppComponent} from "./attribute_app.component";    //importing component function

bootstrap(AppComponent);

Now we will create a component in TypeScript(.ts) file which we will create a view for the component.

attribute_app.component.ts
import {Component} from 'angular2/core';
import {ShoppingListComponent} from './shopping-item.component';

@Component({
    selector: 'my-app',
    template: `
    <shopping></shopping>
    `,
    directives: [ShoppingListComponent]
})
export class AppComponent {

}
  • The @Component is a decorator which uses configuration object to create the component and its view.

  • The selector creates an instance of the component where it finds <my-app> tag in parent HTML.

  • Next we create a directive called ShoppingListComponent which will be accessed from the shopping-item.component file.

shopping-item.component.ts
import {Component} from "angular2/core";
import {NgSwitch} from "angular2/core";
import {NgSwitchWhen} from "angular2/core";
import {NgSwitchDefault} from "angular2/core";
import {NgClass} from 'angular2/common';

@Component({
   selector: "shopping",
   template: `
       <h2>Shopping Items</h2>
       <ul>
          <li
          *ngFor="#shopItem of shopItems"
          (click)="onItemClicked(shopItem)"
          >{{ shopItem.name }}</li>
       </ul>

       <span [ngSwitch]=selectedItem.name>
         <p>You selected :
            <span *ngSwitchWhen="'Shirt'">Shirt</span>
            <span *ngSwitchWhen="'Pant'">Pant</span>
            <span *ngSwitchWhen="'Sarees'">Sarees</span>
            <span *ngSwitchWhen="'Jeans'">Jeans</span>
            <span *ngSwitchWhen="'T-Shirt'">T-Shirt</span>
            <span *ngSwitchDefault>Nothing</span>
         </p>
       </span>

       <div [ngStyle]="setStyles(selectedItem.name)" class="text-success">
          Thank you for Selecting an item!!
       </div>

       <button [ngClass]="{active: isActive}" (click)="isActive = !isActive">Buy Items</button>
   `,
   styles: [`
       .button {
          width: 120px;
          border: medium solid black;
       }
       .active {
          background-color: red;
       }
       p{
          font-weight: bold;
       }
   `]
   directives: [NgClass]
})

export class ShoppingListComponent {
   public shopItems = [
      {name: "Shirt"},
      {name: "Pant"},
      {name: "Sarees"},
      {name: "Jeans"},
      {name: "T-Shirt"},
   ];
   public selectedItem = {name: ""};
   onItemClicked(shopItem) {
      this.selectedItem = shopItem;
   }
   setStyles(item) {
      let styles = {
        'font-size'  : item? '24px'   : 'none',
        'visibility' : !item? 'hidden' : 'visible'
      }
      return styles;
   }
}
  • The local variable shopItem can be referenced in the template and get the index of the array. Angular 2 will bind the model name from the array with the local variable of template.

  • When you click on the item value, the onItemClicked() event will get activate and Angular 2 will bind the model name from the array with the local variable of template.

  • The NgSwitch directive inserts the nested elements based on which match expression matches the value obtained from the evaluated switch expression. It displays an element whose *ngSwitchWhen matches the current ngSwitch expression value.

  • The onItemClicked() method uses local varaible 'shopItem' as parameter and display the selected item by using the selectedItem object.

Output

Let's carry out the following steps to see how above code works:

  • Save above HTML code as index.html file as how we created in environment chapter and use the above app folder which contains .ts files.

  • Open the terminal window and enter the below command:

    npm start
  • After few moments, a browser tab should open and displays the output as shown below.

OR you can run this file in another way:

  • Save above HTML code as attribute_directive.html file in your server root folder.

  • Open this HTML file as http://localhost/attribute_directive.html and output as below gets displayed.

Advertisements