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("myangularapp", []);
myangularapp.directive('customdirective', function () {
    var directive = {
    restrict : 'E', // restrict this directive to elements
    template: "<input type='text' placeholder='Enter message...' ng-model='message' />" +
        " Your Message : {{message}}"
    };
    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

The installer was interrupted before application could be installed. You need to restart the installer to try again

In this post, I am going to share one error that I faced couple of times earlier and its resolution.

Issue –

You have created a installer using Web Setup project with VS 2010. Using this you used to install the application on IIS7.5. Now you got a new machine with IIS7.5 installed (or you installed manually). Now after making the required changes, when you are installing with the MSI, you are getting the following error.

msierrorNow as per the message, you restart the installer but you get the same message again.

As, you don’t get the enough information here so you check the Event Viewer but you don’t find any error there. When you carefully see then you find two info entries there with the messages

1- <Application Name> — Installation failed

2- Windows Installer installed the product. Product Name <Application name and details>. Manufacturer Name – <manufacturer name>. Installation success or error status 1603.

From all the above information, there is no indication about the actual cause of the error. From the above error code if you search on Internet, you will find different resolutions but not the one discussed here. At least I didn’t the below resolution for the above problem.

Note – The above message or code that we found looks like common for many other errors so there could be different resolutions based on scenario.

Solution

One of the possible reasons that it is not getting installed because IIS6 management compatibility is not configured on IIS. So let’s see the steps to configure it.

1) Go to Control Panel -> Program and features -> Turn Windows Features on or off

2) Click on Internet Information Services and it should look like

IIS6Compatibility-No3) If IIS6 management compatibility is not checked then it could be a issue. Please select it as

IIS6Compatibility-Yes4) And click Apply/Ok.

Once the above steps completes. You should be able to install the installer on your machine.

Cause

Now let me briefly discuss that What is IIS6 management compatibility and why the issue surfaced in the above case?

IIS7+ is completely overhauled and there are many breaking changes in it. IIS7 introduced two modes Classic and Integrated mode. Integrated mode combines the modules of IIS and ASP.NET when application runs in Integrated Mode. All the metadata moved to different file in IIS7. So If an application uses the features of IIS6 then it should configure the IIS6 management compatibility in IIS7.

Now the question arises that why do we need this?

Visual studio 2010 installer still targets the older version of IIS (means IIS6) although IIS7 was publicly available in 2008. That’s why IIS6 compatibility is required.

Hope this post will help you.

Thanks,
Brij

 

Wishing you a very Happy New Year – 2015

happy-new-year-2015-imagesAs 2014 came to end and we have just entered to 2015, I am wishing a very Happy New Year to you and you loved ones. New year brings new ideas, new challenges and lot more opportunities. May you rediscover new strengths, garner faith in you, to face the challenges and reach to new heights in your career. As saying Good health is True Wealth , be healthy throughout the year and enjoy each moment.

Also, I would like to thank to all of my elders, friends, blog readers, audiences for their support and candid feedback throughout the year. Hope you all have enjoyed last year posts/videos and that would have helped you professionally. This year again, I will devote more energy and time to my blog to share my leanings.

Keep sharing your feedback that works as a booster for me and let me know if you want to see any specific items in coming days.

Again thanks a lot to all you. Be healthy and be safe.

Happy learning,
Brij

 

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

This is eighth part in the series of AngularJS and I hope you are enjoying this series.  In last post of the series,  We discussed about Data binding in AngularJS and we saw that how it is different than normal classical bindings. In this post we’ll unravel the magic behind the data binding and discuss key concepts involved.

If you want to go through the the earlier posts in this series the here are the links

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

I will suggest you to go though the last part of the series (Data Binding in {{AngularJS}} – Part 7) before going through further. It will help in better understanding the topic.

Before moving directly to the concepts behind the scene, Let’s discuss prerequisites that will help in understanding the whole concept. So let’s start from the scope.

What is Scope?

Scope is the core of an Angular application. It refers to an application model and execution context. An application has single $rootscope and multiple $scope objects associated to it. $scope is accessible between view and controller and it is the only medium of communication between both. It is like a container and holds all the other required information that is used by Angular for providing other features. You’ll see some in this post.

So before moving ahead, let’s understand that how browser identifies an event and takes the necessary actions. The flow of an event handling works as

NormalJS event FlowEvents could be fired in many scenarios like page load, some response comes from server, mouse move, button click, timer events etc.

When we use Angular in a application, It modifies the normal JavaScript event flow and provides its own event handling model. This event handling model comes in flow when event is processed through Angular Execution context. It also provide many other features like exception handling, property watching etc. All the events that we define using angular constructs, is part of Angular Execution context. But you must have seen that when we try to use normal JavaScript or jQuery event then it does not fire. Hold On!!  we will discuss it and its workaround at later part of the post.

So we have understood the basics, now lets come to the main topic and discuss how data-binding works in Angular. There are two steps involved in it.

1- Angular creates a $watch list that is available under scope.$$watchers. Every element that accessed in UI using some directive, a watch is created for that and got a place in this list.

2- Whenever a event (already discussed earlier in this post) occurs, all the watchers get iterated (also known as digest loop) and it is checked if any of the data got changed (called dirty-checking). If yes then it updates the UI or the underlying model.

Let’s understand the above points in detail. The key concepts are

1- $watch and $watchlist

2- $digest loop

3- $apply (Looking new? Got discussed in detail later section)

4- Dirty checking etc

What is $Watch list ?

It is the key of data binding and as discussed above that when a item is accessed in UI via angular directive, an entry gets created in the watch list for that item. Now can you imagine the number of watchers in an application? It could be way high than what you think. We’ll see that in coming section. Let’s see some examples

1- $Watch gets created for elements that are bound to UI. Say I have created some properties as

JS (controller)-

appModule.controller('myController', function ($scope) {
    $scope.message1 = 'message1';
    $scope.message2 = 'message2';
    $scope.helloMessage = &quot;Hello&quot;;
});

HTML (View)-

    <div ng-controller="myController">
        Message - {{helloMessage}}
    </div>

So here only one entry will be created in the watch-list as only helloMessage is accessed in UI. Other properties like message1, message2 that are part of $scope but watchers would not be created for those as there are not accessed in UI.

2- For each ng-model attribute, one item gets created in watch-list. As

<input type="text" ng-model="talkName" />
<input type="text" ng-model="speakerName" />

Here, we have two input controls with ng-model as talkName and speakerName. For both, there will be an entry get created in watch list. $scope.talkName and $scope.speakerName are bound to first and second input respectively.

3- We have used ng-repeat in our earlier post, which renders the elements in UI based on the available list of items. How  many watchers will be created in that case. Let’s take example from the last post, where I have shown the list of talks on UI by using ng-repeat.

JS –

eventModule.controller(&quot;eventController&quot;, function ($scope, EventsService) {
    EventsService.getTalks().then(function (talks) { $scope.talks = talks }, function ()
    { alert('error while fetching talks from server') })
});

Here Talks comes from server which contains (Say six items) in the list.
HTML:

    <div class="row">
        <table class="table table-condensed table-hover">
            <tr ng-repeat="talk in talks">
                <td> {{talk.id}}</td>
                <td> {{talk.name}}</td>
                <td> {{talk.speaker}}</td>
                <td> {{talk.venue}}</td>
                <td> {{talk.duration}}</td>
            </tr>
        </table>
    </div>

How many watchers get created for the above?
It would be 5*6 = 30. (Properties bound in UI * number of items in the list ).

As I mentioned in my post earlier, number of watchers could be very high because if you have used many ng-repeat in your page then it would grow exponentially.

4- We can also create the watch programmatically. Let’s see the example

HTML :

    <div ng-controller="myController">
        <input type="button" value="UpdateHelloMessage" ng-click="updateHelloMessage()" />
        {{message1}}
    </div>

JS:

appModule.controller('myController', function ($scope) {
    $scope.message1 = 'Test Message';
    $scope.helloMessage = &quot;Hello&quot;;

    $scope.updateHelloMessage= function () {
        $scope.helloMessage = &quot;Hellow World!!&quot;;
        console.log($scope.helloMessage);
    };

    $scope.$watch('helloMessage', function (newVal, oldVal) {
       if(newVal != oldVal)
            $scope.message1 = &quot;Hello message updated&quot;;
    });
});

If we see the HTML then we’ll say that there are only one watch (for message1) in this app. But it has two as I had added a watch on $scope.helloMessage programmatically. When we click on button UpdateHelloMessage, $scope.message1 also get updated due to new watch created and gets reflected on UI.

Before moving to next topic, let’s understand when does an entry get created and added in watch list.

When does an entry get added in the watch list?

Angular uses it’s own compiler which traverses the UI to get all the angular directives used. This is how angular directives used in the HTML are understood and accordingly rendered in UI. Angular process can be depicted as

ngCompilingProcessAs we can see there are two main steps involved : Compile and Linking.

1- Compile process – It traverses the DOM and collects all the directives and passes it to the linking function.

2- Linking – It actually combines all the directives and assigns to a scope. It sets up $watch expression for each directive. $watch actually responsible to notify the directive in case of a change in property of $scope, then it get reflected in UI. Similarly, if any changes occurs in UI as by some user interaction, it get reflected in model. Here one point to be noted that both controller and directive has the ability to access the scope but not each other.

So here we can understand the entries in watch list, get created in linking phase. And this is where it knows the number of watch need to be created in case of ng-repeat. We’ll see some examples later.

$digest loop 

Earlier in this post, I mentioned that whenever an event occurs on browser, digest loop gets fired. It contains two smaller loops, one processes $evalAsync queue and other iterates the watch list for each item, to detect the changes. Then, it finds all the items which got changed and UI gets updated accordingly.

Note – The $evalAsync queue is used to schedule work which needs to occur outside of current stack frame, but before the browser’s view render. It provides the similar features provided by setTimeout().

What is dirty checking?

The process of checking every watch to detect the changes, is called dirty checking. There could be two scenarios

First –

digest-nochangeSecond –

digest-chnageIn second case, loop continues till it finds no changes in the entire loop. And once it completes, DOM gets updated if required.

So till now you must have understood that magic of data binding occurs in AngularJS. We had one more key item left apply that we didn’t discuss in detail. Whats the use of that?

$apply – It actually plays pivotal role in the whole process. Angular does not trigger the digest loop directly, it has to be triggered via $apply call and this method is responsible to enter the execution in Angular Execution context. Only model modifications which execute inside the $apply method is properly accounted for by Angular. So now question arises that even we did not call the $apply in any earlier examples still it is working as expected. Actually Angular does it for us. Angular wraps every event with apply so that digest loop gets fired.

What are other uses of apply method?

As we have already seen that angular wraps every event with apply that fires digest loop. It means if we want to run the digest loop in some scenarios then we need to execute the apply method. You must have seen many times that whenever we make some changes using JavaScript or jQuery methods it is not reflected in Angular. In those scenarios apply method provides entry in Angular Execution context. Let’s see it with an example.

HTML :

    <div ng-controller="myController">
        <input type="button" value="UpdateHelloMessage" ng-click="updateHelloMessage()" />
        {{helloMessage}}
    </div>

JS :

appModule.controller('myController', function ($scope) {
    $scope.helloMessage = &quot;Hello&quot;;

    $scope.updateHelloMessage = function () {
        setTimeout(function() {
            $scope.helloMessage = &quot;Hello World!!&quot;;
        }, 0);
    };
});

So what do you think about the above code? Would it work as expected?  I mean when you click on the UpdateHelloMessage button, updated $scope.helloMessage (Hello World!!) would reflect on UI.
No It wont work.

Although the model $scope.helloMessage will get updated but it wont appear on UI because digest loop wont run in this case. But why digest loop wont run? Because the value is updated in setTimeout method which is java-script method and it won’t run in Angular context. So to get it running as expected we need to call $scope.$apply() and that would trigger digest loop and updated value will be shown on UI. So we can update the JS as

appModule.controller('myController', function ($scope) {
    $scope.helloMessage = &quot;Hello&quot;;

    $scope.updateHelloMessage = function () {
        setTimeout(function() {
            $scope.helloMessage = &quot;Hello World!!&quot;;
            $scope.$apply();
        }, 0);
    };
});

Now it will work as expected. Now you must have understand that there is no magic but a simple logic is written to do that.

Hope you have enjoyed this post. Please do share your feedback and let me know if you want to see any specifc topic here.

Happy Learning
Brij

DataBinding in {{AngularJS}} – Part 7


This is the seventh post in the series of AngularJS and today, we will discuss one of the features that we already used -Data Binding in details. For earlier posts of the series, please refer the links 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

Let’s just take a quick look on our picture trackerpicture-tracker

Broadly, Data binding can be divided in the two parts
– One way binding
– Two way binding

Continue reading