Presenting on ASP.NET 5 in #GIDS2015

GIDS_Website_LogoThe Great Indian Developer Summit (GIDS) is the largest and most popular annual conferences of India. This year it is taking place during April 21-24, 2015. I am very excited to share that I will be presenting there on ASPNET5 which was always very near to me . This version is bit different from earlier releases due to the massive changes that are taking place with it in this version. All the slides and the demos will be shared at the end of session. The details of of Talk are as below

BrijB1

Building Modern Web Applications with ASP.NET 5

ASP.NET 5 is now redesigned to cater to the needs of modern web applications. With the redesign, you can now  use the latest best practices such as dependency injection, TDD etc. ASP.NET 5 curtails many modules and components that we normally don’t use in our projects and hence boosts application speed. In this session we will examine the design shift that took place within ASP.NET 5 and how it resolves several of the problems that we encounter in our coding lives. At the end of session, you will have a good idea on the changes that ASP.NET5 brings to you as a developer.

If you are visiting this time, I will highly recommend to join this session for an hour and explore the awesomeness of ASP.NET 5. This session will be driven by demos with lots of Interactions

I am very excited to see you all there.

Cheers,
Brij

What is View component: ASP.NET 5

This is the second post on ASP.NET 5. In this post, we are going to explore one another very useful feature of ASP.NET 5. The link of my earlier post on ASP.NET 5 is

 Getting started with Tag Helpers – ASP.NET 5

ASP.NET 5 comes with another version of ASP.NET MVC that is ASP.NET MVC6.View Component is another very powerful got added with MVC 6. If you have not already gone through with this feature, you might just keep guessing about it and may correlate with multiple things. But this feature when you go through, you will enjoy it.

Before discussing this, How many of used Child Actions or know about that?

If you have used that you must have find it bit nasty. Child Actions are like a normal action but it can not be called by directly from url instead it is called from a view. The key usage of Child Action, when we want to reuse some part of UI at multiple places then we create a child action and use it at multiple places. One of the key issues was that with this, it makes another request to the server to call the action method, by going through the whole life cycle which makes the application slow. Also It can not be invoked asynchronously.

View Component provides us capability to write a component that generates a part of the UI similar to Partial View . It can be reused on  different places based on the requirement. One of the classic example could be a shopping cart that is visible to user on every page and many similar others. Now you no longer need Child Action after using it.

So How to create a ViewComponent ?

There are two part of that

1- Create a class that derives from class ViewComponent

2- A razor view which will be using the ViewComponent class by calling its method.

You can think of the class as a mini-controller and another one as a view. Let’s create an example,

Say I want to show Top Users of the website and showing them on each page in a section. So let’s create a View Component Class

 public class TopUsersViewComponent : ViewComponent
	{
		public IViewComponentResult Invoke(int TopUserCount)
		{
			var items = GetUsers().OrderByDescending(u => u.Points).Take(TopUserCount);

			return View(items);
		}

		public IList<UserInfo> GetUsers()
		{
			IList<UserInfo> users = new List<UserInfo>()
				{
				new UserInfo() { UserName = "Amit", Points= 1000 },
				new UserInfo() { UserName = "Brij", Points= 1500 },
				new UserInfo() { UserName = "Rahul", Points= 500 },
				new UserInfo() { UserName = "Vivek", Points= 400 },
				new UserInfo() { UserName = "Gaurav", Points= 600 },
				new UserInfo() { UserName = "Abhijit", Points= 1200 },
				new UserInfo() { UserName = "Peter", Points= 1100 },
				new UserInfo() { UserName = "Satya", Points= 300 }
				};

			return users;
		}
	}

Few points –

1- Note here that the class name ends with ViewComponent and the name would be TopUsers only similar to controllers. If you don’t want to add this suffix then you can provide an attribute on the class as [ViewComponent(Name = “TopUsers”)] then you can give whatever name you want.

2- Here Invoke would be fired and for each View Component instance. We can pass as many parameters as we require. There is async version of this method is also available which can be very useful if you are connecting to some third party component or you know this would be long process.

We have already created the class. Now lets create the View. Here we need to follow certain structure to create the View. For this example, I have created a MVC controller named as DemoController and created an Index view. As We are going to use the View Component here, we need to create the folder structure like Views\<ControllerName>\Components\<ViewComponentName>\. For this example it is as Views\Demo\Components\TopUsers\. So we need to create a view in this folder as Default.cshtml. It is as

@model IEnumerable<WebApplication1.Models.UserInfo>

<h3>Top Users</h3>
<ul>
@foreach (var user in Model)
{
<li> <img src= @user.ProfilePic /> @user.UserName</li>
}
</ul>

So we have created a View Component named as TopUsers. Now lets use this in View. It would be as

<div class="col-md-4">
@Component.Invoke("TopUsers", 3)
</div>

It’s simple. We need to pass the name of the View Component and other parameters of Invoke method. Now it’s time to run the code. So it’s look like
DemoEx

The encircled content is rendered via View Componet. Now we can use this as many places as we require. So now there is no need of Chiild Action and Partial Views.

Hope you have enjoyed the post and this new feature. I will posting some more post on the new feature and changes in ASP.NET5.

Happy Learning,
Brij

Getting started with Tag Helpers – ASP.NET 5

ASP.NET has been always near and dear to me and it got more exciting for me as ASP.NET5 got revolutionary changes comparing to previous versions. All the changes has been done considering key points that are driving the software evolution like Agility, embracing latest design standards and technologies. It provides more capabilities, more power to developer, follows latest standards and helps in writing Cloud and mobile ready applications. As we know ASP.NET is like a umbrella of technologies and consists of ASP.NET MVC, ASP.NET WebForms, ASP.NET web api etc. All these technologies got lots of change and design to serves the modern web apps. ASP.NET5 comes with another new version of ASP.NET MVC6. I will be writing couple of posts on cool features of ASP.NET 5 that actually makes our life easy as a developer.

In this post, I am going to discuss one of the main features of ASP.NET 5 that I really liked a lot. When razor syntax was introduced, it looked different and sometimes uncomfortable to me. There were multiple reasons. First thing, I loved the idea of writing C# code at in different file as code behind because it gave clear separation of markup and c# code. It also provided to leverage the real IDE power like intellisense for html, css, JavaScript, other plugins and was easily integrable with other plugins. Razor removed the concept of code behind and allows us to write to inline C# code. Although it is powerful at certain times but it is confusing sometimes as well and make a markup writing experience very bad. Because here we were not writing the HTML actually we were writing a mix and match of html and some C# methods that renders the html while executing at run time. So we used to get the issues while running the code only.

We have used a inbuilt HTML helpers in razor forms a lot and created custom helpers when required. Our normal Razor view looks like

// LOOSELY TYPED VIEW
<div class="editor-label">
// For Label
@Html.Label("Name", new {id= "lblName"}
</div>
<div class="editor-field">
// For textbox
@Html.Editor("txtName")
</div>
// For action link
<li>@Html.ActionLink("Home", "Index", "Home")</li>
// STRONGLY TYPED VIEW
@Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
    @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
    @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" })
</div>

In above example, top three html helpers : for label, textbox and link are loosely typed view and last sectionis part of a  strongly typed view .  As earlier mentioned, we can see that it is combination of HTML and inline C# which we start with @. While rendering these html helpers methods gets called which returns the html that is rendered in browser.

ASP.NET 5 introduced new features named as TagHelpers. This is going to make developers life very easy and make the form, readable, maintainable and manageable.

First thing how to use

As we all know that in ASP.NET 5, the features were developed as independent components and can be added on demand via nuget. So we need to add it via nuget.

  1. Add Microsoft.AspNet.Mvc.TagHelpers

2 Then add it in View where you want to use this feature as @addtaghelper “Microsoft.AspNet.Mvc.TagHelpers”

Now I can use the awesomeness of tag helpers in our view. We can remove the below line

@Html.LabelFor(m => m.UserName, new { @class = “col-md-2 control-label” })

and instead can use

<label for=”UserName” class=”col-md-2 control-label” style=”color:red”></label>

It will work same as HTML helper. Under the hood the tag helper convert it to similar earlier lambda expression to get the property name.

Similarly for input

@Html.TextBoxFor(m => m.UserName, new { @class = “form-control” })

can be replaced with

<input form=”UserName” class=”form-control” style=”color:red” />

I have taken register page of starter web application which is as

razor-registerLooks as below after replacing normal razor syntax with tag helpers

taghelper-registerThis is awesome right. Now it looks cleaner, manageable and the best thing is you’ll get all the intellisense feature for HTML, css, javascript etc.

It’s not just yet. It also gives us power of creating our own tag helpers which we can create based on our need and render the appropriate html at runtime.

How to create Custom Tag Helper :

Creating custom tag helper is very easy. One need to create a class that inherits TagHelper class. So here we need to override one of these methods

1-  public override void Process(TagHelperContext context, TagHelperOutput output)

2-  public override void ProcessAsync(TagHelperContext context, TagHelperOutput output)

ProcessAsync is the asynchronous method that we can use if we need to do some long operations like getting data from database, calling any third party services etc. It has two parameters of .type TagHelperContext and TagHelperOutput. TagHelperContext  context contains the execution context for Taghelper and TagHelperOutput that contains the information that is required to generate the html. Here we provide all the details of html tags that will be generated while rendering

So for an example, I am going to create a simple status tag helper which displays different color based on some data. So my custom tag helper looks like

[ContentBehavior(ContentBehavior.Replace)]
    public class StatusTagHelper : TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            int status;
            output.TagName = "img";
            Int32.TryParse(context.AllAttributes["val"].ToString(), out status);
            if (status == 0)
            {
                output.Attributes["src"] = "images/green.png";
            }
            else if (status == 1)
            {
                output.Attributes["src"] = "images/red.png";
            }
            else
            {
                output.Attributes["src"] = "images/blue.png";
            }
        }
    }

This custom tag is used as

<div class="form-group">
    <label class="col-md-2 control-label"> Status</label>
    <div class="col-md-10">
        <status val="1"></status>
    </div>
</div>

Now if we see the C# code then you can find that attribute val is read from the context object and the details of the HTML tags are provided with the output object. One other item, you must be seeing the ContentBehavior attribute, what is the need? It plays a vital role in the tag helper. It tells that the way tag helper would render. Like here, I have used Replace, which means the tag used in cshtml will be replaced. There are four other options – None, Prepend, Append, Modify. It behaves as the name suggests, I will leave this for you guys to explore.

Let’s see the code running

customtaghelperHere the val is assigned to 1 and based on that image is rendered.

This is a simple example that I showed here to explain the Tag Helper. Creating taghelper is very simple and very flexible. Hope you have enjoyed the post. Wait for more articles on ASP.NET 5.

Happy Learning,
Brij

ASP.NET MVC and Angular Routing together – Part 11

[To view earlier posts of the series – Click Here]
This will be short but very helpful post. I have seen lots of questions and confusion over Angular Routing and ASP.NET MVC Routing. In this post, I will try to unravel. We all already know the following two points 1- ASP.NET MVC is a server side technology so it means ASP.NET MVC routing takes place at Server.. 2- AngularJS is a client side technology so Angular routing itself cannot conflict with ASP.NET MVC in any way. But it works on the top of the ASP.NET MVC. Let’s discuss it with a example. I will be taking the sample from one of my earlier posts (Learning {{AngularJS}} with ASP.NET MVC – Part 5) on AngularJS and modify a bit for this post. Let me brief about the\example 1- It has one MVC controller – named EventsController that has three methods. One returns the index view and in rest of the two, one returns a list of talks and other, list of speakers in JSON format. 2- It has two angular routes, one for listing speakers (/Events/Speakers) and another from listing talks (/Events/Talks). These urls are used in top menu. So when we run the application and the url (http://localhost:<port>/ or http://localhost:<port>/events or http://localhost:<port>/events/index) the page loads as homeAfter clicking the the two tabs talks or speakers are loaded accordingly. Angular Routes in the sample are defined as

var eventModule = angular.module("eventModule", []).config(function ($routeProvider, $locationProvider) {
 //Path - it should be same as href link
 $routeProvider.when('/Events/Talks', { templateUrl: '/Templates/Talk.html', controller: 'eventController' });
 $routeProvider.when('/Events/Speakers', { templateUrl: '/Templates/Speaker.html', controller: 'speakerController' });
 $locationProvider.html5Mode(true);
 });

Now if we access the direct angular defined routes it does not work. Let’s understand why? When we access the url http://localhost:48551/events/index then it actually calls the MVC EventsController and Index action as expected and loads the page. Now when we click on one of the tabs (say speaker) then Angular chips in and it loads the angular view. The call does not go to MVC controller and action at server rather it gets handled at client side by Angular. It loads the data via angular service that initiates the ajax call to server to get the data. Here the url changes but handled at client side only and server (or say ASP.NET MVC) does not even get to know about it. Now the next question, in second case, why the call does not go at server? In first case, there is nothing available at client side and request goes to the server and gets the page. When page loads it loads everything including angular library. Now when second time, the url gets changed Angular checks whether it can handle the url if yes then it just process it at client side only and if it can not then leave the request as is to get handles from server. The whole process can be defined it pictorially angular Now we can imagine a scenario while accessing a Angular defined url (http://localhost:48551/Events/Talks) as initial request, it finds nothing at client side which can handle it as it is a fresh request. And it goes to server and tries to find the EventsController and Talks action but it is not defined by ASP.NET MVC so it does not work. We just have Index action at MVC controller. Now how to resolve this issue? As Initially in this post, I pointed out that Angular defined urls are handled at Client side only, so AngularJS must be loaded and initialized before it can handle the request. There would be two steps involved 1- All angular defined urls should be mapped to some MVC route that returns the response to client with all the client side libraries including Angular. 2- Then as angular is initialized, it handles the url as discussed earlier When we try to access an angular defined urls as first request, it goes to server then we need to initialize the page first with AngularJS then rest angular takes care.It means that in the example, we need to call the index action when somebody try to access the AngularJS urls (Talks and Speakers) directly which will load the page and it will initialize the Angular as well then the Angular urls will be handled by angular itself. So how to do that, we just need to add some routes in Global.asax of so that even if Angular defined urls are called it returns fires of the index action only. So we can add it like

 public static void RegisterRoutes(RouteCollection routes)
 {
 routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
 routes.MapRoute(
 name: "EventsCourses",
 url: "Events/Talks",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 routes.MapRoute(
 name: "EventsSpeakers",
 url: "Events/Speakers",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 
 routes.MapRoute(
 name: "Default",
 url: "{controller}/{action}/{id}",
 defaults: new { controller = "Events", action = "Index", id = UrlParameter.Optional }
 );
 }

So here I added two routes EventsCourses and EventsSpeakers for Angular Urls and for both, index action of events controller gets called. Here we should not have a URL which can be processed by Angular and MVC both in that case you will get different behavior in both the case so we should keep in mind while defining the URLs. So I hope it must have been clear to you. Also you do not need to add each AngularURL as new route in Global.asax, you can have unique pattern in Angular URLs and for that pattern, you can have just one route which return the same action for that pattern. Sample is attached with the post. Happy Learning Brij

Create Custom Directive using Isolate scope in AngularJS – Part 10

This is the tenth post in the series of AngularJS (Get the list of all previous posts, click here) and this post in the continuation of last post where we have discussed the basics of custom directive (I will recommend to read last post before continuing, Click here to see previous post) but the real value of a custom directive, if it is reusable and can be independently used at many places. If you are using the parent scope directly in your scope then it wont be reusable. One more side effect, if the parent scope gets updated then your custom directive will also be affected even if you don’t want. Not clear? Let’s see an example

var myangularapp = angular.module(&amp;quot;myangularapp&amp;quot;, []);
myangularapp.directive('customdirective', function () {
    var directive = {
    restrict : 'E', // restrict this directive to elements
    template: &amp;quot;&amp;lt;input type='text' placeholder='Enter message...' ng-model='message' /&amp;gt;&amp;quot; +
        &amp;quot; Your Message : {{message}}&amp;quot;
    };
    return directive;
});

I have created a directive where user is allowed to enter some message as it and created multiple instances of same directive as

<customdirective> </customdirective> 
<customdirective> </customdirective> 
<customdirective> </customdirective>
 

Now let’s see it running

normalHere we can see that even we are changing the values in one directive but its getting reflected in all the directives. It is because all are accessing the same scope. Certainly we don’t want this. This problem can be resolved using isolate scope.

What is isolate scope ?

The problems that we discussed above, can be resolved by isolate scope. We can isolate the scope easily that is used in the custom directive. To add isolate scope, we need to add the scope property while defining the directive. It also makes sure that parent scope is not available to the custom directive.

But now the question arises how will the directive interact with the outside world? Because the directive cannot be useful if it works in complete isolation. To handle it, Isolate scope provides us three options to communicate to isolate directive that is also known as Local Scope properties. These are
localscopedirectivesLet’s discuss each in details

@ or @attr : @ provides us capability to pass a value to custom directive in string format. I have made the string format as bold because I wanted to highlight it, here we cannot pass an object. If you pass an object it will be treated as string format only and accordingly displayed. Also, it works like one way binding it means if the data changes in parent scope, then it reflects in the directive as well as

onewaySo here we find that a change takes place in parent scope, it reflects in directive itself but vice versa is not true. If it gets changed inside directive, parent scope does not get affected. Now, How to create the directive?

onewaycodeSo here we have created a directive and used it. The details of three points (in pic) are

1- talkname is a property in the isolate scope and it is only accessible in directive itself

2- @talk means that this would be the attribute name in the custom directive that will be used to communicate. We can also write scope : { talkname: ‘@’ }, in this case, talk and talkname both would be same. In this example, I have used different name for better understanding.

3- This is passed from parent scope. As I mentioned in earlier section, that if parent changes then it would reflect in directive as well.

The complete code is as

<script language="javascript" type="text/javascript">
    var myangularapp = angular.module("myangularapp", []);
    myangularapp.controller("mycontroller", function ($scope) {
        $scope.talk = { name : 'Building modern web apps with ASP.NET 5', duration : '60m'}
    });
    myangularapp.directive('attrcustomdirective', function() {
        var directive = {
            restrict : 'E', // restrict this directive to elements
            scope : { talkname: '@talk' },
            template : "<div>{{talkname}}</div> ", 
        };
        return directive;
    });
</script>
</head>
<body ng-app="myangularapp" ng-controller="mycontroller">
    <attrcustomdirective talk="{{talk.name}}" /> 
</body>

Now let’s move to another type.

= or =attr :

Unlike the @ property which allows us to pass only string value, it allows us to pass the object itself to directive. And the data also gets synced in parent and child scope like two data binding. If the data changes from inside the directive it reflects in parent scope.

bindHere talk (whole object) is passed in directive and assigned to talkinfo. Now whether the talk or talkinfo gets updated both remains always in sync. bindcodeWe can see from above that how the directive got created with = and its uses. The details of three points (in pic) are

1- talkinfo here is the object that that got received via talkdetails. You can see, I have accessed the value of talkinfo three times via its properties.

2- talkdetails is attribute name that is used to pass the object via directive. Similar as earlier if we don’t provide the attr as scope : { talkinfo: ‘=’ } then the attribute name will be talkinfo only.

3- talk is the scope object that is assigned to talkdetails.

The complete example will be as

<script language="javascript" type="text/javascript">
    var myangularapp = angular.module("myangularapp", []);
    myangularapp.controller("mycontroller", function ($scope) {
        $scope.talk = { name : 'Building modern web apps with ASP.NET5', duration : '60m'}
    });
    myangularapp.directive('bindcustomdirective', function() {
        var directive = {
            restrict : 'E', // restrict this directive to elements
            scope : { talkinfo: '=' },
            template: "<input type='text' ng-model='talkinfo.name'/>" +
                "<div>{{talkinfo.name}} : {{talkinfo.duration}}</div> ",
        };
        return directive;
    });
</script>
</head>
<body ng-app="myangularapp" ng-controller="mycontroller">  
    <bindcustomdirective talkdetails="talk"/>{{talk.name}}
</body>

Let’s move to last Local scope property.

& or &attr

This is the third and last isolate local scope property. It allows us to wire up external expression to the isolate directive. It could be very useful at certain scenario, where we don’t have details about the expression while defining the directive like we want to call some external function when some event occurs inside the directive based on requirement.
expressionIn the above pic, we see that we have function with name method that is passed to directive as via the attribute named expr. Let’s see how do we create the directive and how different property and attributes are co-related.

exprcodeIn the example above, I have used two directives & and @. @ is just used to support this example. Although you must have understand the three points that I have used in the above pic as it is similar to earlier but let me explain it once more in this context. In this example, we are updating an object that gets updated and reflected in the directive as well because of one way binding behavior of @ local scope property

1- method is the property of inner scope here so it is used to access the passed method

2- expr is the attribute name that is used in the directive to pass the expression or defined method. Behavior would be same as earlier local scope property if we just write scope : { method: ‘&’}

3- UpdateData() is the method name that we want to pass in the directive and it is defined as part of parent scope.

4- This value gets updated when we click on Update Data button that calls UpdateData() method which updated the object Talk.

Let’s see the complete example.

<script language="javascript" type="text/javascript">
    var myangularapp = angular.module("myangularapp", []);
    myangularapp.controller("mycontroller", function ($scope) {
        $scope.talk = { name: 'Building modern web apps with ASP.NET5', duration: '60m' }

        $scope.UpdateData = function () {
            $scope.talk = {
                name: 'Working with AngularJS',
                duration: '45m'
            };
        };
    });
    myangularapp.directive('expcustomdirective', function() {
        var directive = {
            restrict : 'E', // restrict this directive to elements
            scope : { method: '&expr', talkname : '@'},
            template: "<div>{{talkname}}</div> <input type='button' " +
                "ng-click='method()' value='Update Data'/> ",
        };
        return directive;
    });
        
</script>
</head>
<body ng-app="myangularapp" ng-controller="mycontroller">
    <expcustomdirective expr="UpdateData()" talkname="{{talk.name}}" />
</body>

Hope you must have got good idea about local scope properties in isolate scope and will be able to decide easily that what to use. Do share your feedback and questions

Happy learning
Brij

Reboot NCR (31st Jan) – A very successful event

Hello All,

In this post, I am going to write the summary of Reboot event that we conducted with the support of Microsoft Gurgaon. It was a full day event and 5 speakers kept the 100+ audience engaged in their sessions throughout the day. I took the second session of the day and talked about the features offered by ASP.NET 5.  Everybody enjoyed the session and amazed with the features that Microsoft bringing with ASP.NET5.

Slides of my session are attached with this post. Just to note that I have used Visual Studio 2015 Beta1 release for the session and as it is not a final release there could be some difference in final release but the concept would be same.

Some of the pics of my session..

IMG_30891975098_10155119890895463_5459032723523304022_n

 

 

 

10957327_10155119889000463_2552868464931909734_n1924536_10155119905620463_5541168978162528134_n

 

 

 

 

 

 

 

 

For more snaps, please click here

Slides of my session are

Hope you all enjoyed the day with fun way of learning. Do let me know if you have any specific feedback.

Cheers,
Brij

Creating custom directive in AngularJS – Part 9

In this post, we’ll discuss how to create custom directive. This is a big topic so I will be discussing in coming couple of posts.As a whole, this is ninth post in series of Learning AngularJS and I hope you are enjoying this series. The link of my earlier posts in the series are below

Learning {{AngularJS}} with Examples–Part 1

Learning {{AngularJS}} with Examples–Part 2

Learning {{AngularJS}} with ASP.NET MVC – Part 3

Learning {{AngularJS}} with ASP.NET MVC – Part 4

Learning {{AngularJS}} with ASP.NET MVC – Part 5

Learning {{AngularJS}} with ASP.NET MVC – Part 6

DataBinding in {{AngularJS}} – Part 7

Data Binding in {{AngularJS}} : Under the hood – Part 8

So let’s come to topic and start from the basics.

What are Directives?

From Angular’s documentation “At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.

So anything that we write in HTML that is handled by Angular are Directives like {{}}, ng-click, ng-repeat etc.

How Directives are handled?

Directives provides us a capability to have more control and flexible way to rendering the html. As we know these are not standard HTML attribute so browser doesn’t understand it. Angular chips in between and reads all the directives and process them to emit the browser readable HTML. So what is the process of handling directives? I already discussed that in my last post, but I am including it here briefly.

ngCompilingProcessSo there are two steps involved here: Compiling and Linking.

Type of Directives

There are four types of directives. These are

  • Element directives
  • Attribute directives
  • CSS class directives
  • Comment directives

Element Directives – Element directives are like HTML elements as

<myElementDirective></myElementDirective>

Attribute Directive – Attribute directives are which can be added an attribute over an element as

<div myAttrDirective></div>

CSS class directives– These directive can be added as an CSS class

<div class="myAttrDirective: expression;"></div>

Comment Directives– Comment directives is represented as

<!-- directive: myCustomAttrDirective expression -->

How to create a custom directive

One of the key benefits of AngularJS is that apart from its built-in directives, it allows us to write our own custom directives so that we can render the HTML on browsers based on our specific requirement. Angular provides us a simple syntax to create our own custom directive.

var myElementDirective = function () {
var myDirective = {};

myDirective.restrict: 'E', //E = element, A = attribute, C = class, M = comment
myDirective.scope: {
// To provide scope specific for that directive  },
myDirective.template: '&lt;mdiv&gt;This is custom directive&lt;/div&gt;',
myDirective.templateUrl: '/myElementTemplate.html',
// use either template or templateUrl to provide the html
myDirective.controller: controllerFunction, //custom controller for that directive
myDirective.link: function ($scope, element, attrs) { } //DOM manipulation
}

The brief description of each property as

restrict Defines the type of directive. Possible values are E (element), A (Attribute), C (Class), M (Comment) or any combination of these four
scope Allows us to provide a specific scope for the element or child scopes
template This contains the HTML content that would be replaced in place of directive. It also could contain any other angular directive
templateUrl Allows us to provide the URL of the HTML template that contains the actual html content similar to above. Set any one of the two.
controller controller function for the directive

So we got the details about creating a custom directive. But the next question is –  How to register it? As we discussed on one my earlier posts (part-2) that Module works as container in AngularJS so the same applies here as well. It means we need to register it with module as directive. We’ll see that coming example.

Let’s create an example

So I am going to create a simple element directive as

    var myangularapp = angular.module("myangularapp", []);

    myangularapp.directive('myelementdirective', function () {
            var directive = {};
            directive.restrict = 'E'; //restrict this directive to elements
            directive.template = "Hello World using Custom Directive";
            return directive;
        });

and HTML is

<body ng-app="myangularapp">
    <myelementdirective></myelementdirective>
</body>

No when we run this page, it will appear as

basicdirectiveexSo here we can see the element myelementdirective is replaced with the text. In this example, I have used only few properties that I discussed.

So here we can see that this is an element directive as restrict is set to E (Element). restrict property can be also set as any combinations of E,A,C,M like EA or EAC. If we set it as EA then compiler will find myelementdirective as an element or attribute and replace it accordingly.

We can also use templateUrl instead of template.  templateUrl will pick the content of the file and use it as template.

Now, Let’s understand the flow of it working

1- When the application loads, Angular Directive is called which registers the directive as defined.

2- Compiler find out any element with the name myelementdirective appears in the HTML.Here, It finds at one place.

3- Replaces that with the template.

So looks simple. Right!! Let’s see another example

    myangularapp.directive('myelementdirective', function () {
            var directive = {};
            directive.restrict = 'E'; //restrict this directive to elements
            directive.template = "Hello {{name}} !! Welcome to this Angular App";
            return directive;
    });

So here we used an interpolate directive {{}} in the template and used name. So we need to provide the value for this. So let’s add a controller to handle that

    myangularapp.controller("mycontroller", function ($scope) {
        $scope.name = 'Brij';
    });

Now when we run the application, Would it work?

directiveintrapolateSo it did work. But in this case, what would be the flow?

As I mentioned earlier that there are steps involved while rendering a page. Compiling and linking. All the data population takes place in linking phase. So during compilation phase it replaced the directive and in linking phase the data got populated from the scope. So earlier steps would be there, just one more steps would be inserted in between 2nd and 3rd.

Using Transclude

This word may look complex but it provides a very useful feature. Till now we have seen that custom directive are just replaced by the template that we provide while creating custom directive but there could be some scenario where we donot want to replace the whole html but only some part of it. Like say I want that the text that is wrapped by the custom directive should not get replaced but only element part. Didn’t get? Let’s see pictorially

Say I created a custom element directive  as myCustomDirective and the template provided for it as <div>Some custom template text<div>
WithoutTransclude

 

 

In case of transclude

WithTransclude

 

 

 

Note – Here I changed the template as <div ng-transclude>Some custom template text</div> to get the transclusion working.

So in the above pic, we can see that the text is not replaced while in case normal directive the whole template replaces the directive.

Now we understood the transclusion so let us see what all we need to do to use it. There are two steps

1- Set the transclude property to true while creating directive.

2- We need to inform Angular that which part contains the transcluded html that’s why for transclusion example, I changed the template a bit (Refer Note above)

Hope you have enjoyed this post. In the next post, we’ll some more interesting feature of custom directives. Stay tuned.

Happy Learning
Brij