Thursday, February 20, 2014

angularjs compilation flow

angularjs compilation does two things.
  • parse the html template and collect all directives. 
  • bind directives with scope and produce the final html
All the directives are handled in orderly fashion. The order is established by two rules.
  1. First, establish the parent-child relationship in the DOM. At this stage, we are talking about the template DOM, not the final html. The directives in parent are always handled first.
  2. Directives with higher priority in the same node are handled before those with lower priority.

Compilation

Step 1 :So give  this example in plunker, the normal order will be like this A1(priority 99)->A3 and form(priority 0),->A2(priority -1)->B1 (child). Once the order is established, the compilation is finished.

Link

Step 2 :controller for each directive is called following the established order.  Each controller has its turn to augment the scope.   The scope is fully established after this step.
Step 3: The link function for each directive is called in reverse order.  So here the order is B1->A2->A3 and form->A1.

The example in the plunker logs all controller call and link function call to console. You can turn on the console to view the compilation and link sequencer.

Let us see how we can use this knowledge to tackle one tough problem I face in one of my project. In one of my project, I need to generate dynamic form whose name is determined by scope property. But the ngForm property only accepts literal text instead of an expression for the form name. How can we tweak the compilation/link process to make the form to accept an expression? This question is also asked in stackflow.

Alter the link flow with terminal property

I replaced A2 with another directive A4 following the suggestion in the stackflow section. A41 is terminal. In the link function, it changes/add form name by evaluating an expression.

testApp.directive("testA41", function($compile){
  
    return {
        terminal:true,
        priority:101,
        restrict: 'A',
        controller: function($scope, $element, $attrs){
            if ($element.controller("form")==null){
                console.log("controller: A41-101:NO form ");
            } else {
                console.log("controller: A41-101: YES form");
            }
        },
        link: function(scope, element, attrs){
            if (element.controller("form")==null){
                console.log("\t link:A41-101: No form");
            } else {
                console.log("\t: link A41-101: YES form");
            }
             element.removeAttr("data-test-a41"); //avoid infinite loop
             element.removeAttr("test-a41");
            attrs.$set("name","test"); //set name

            $compile(element)(scope); //recompile
        }
    };
});




 In step 2, the controller is called by the order A41(priority 101)->A1->A3 and form(priority 0)->B1 (child). Since A41 is terminal, A1->A3 and form(priority 0)->B1 (child) is never called. The normal flow is interrupted.
In step 3, only A41 is called, all others are skipped. Inside A4's link function, A4 removes itself from element and use $compile to start a compilation process. Basically A4 asks angularjs re-perform step 1, step2 and  step 3.  But this time, form name is set.

communicate with each other through controller

angularjs suggests directives comunicate with each other through link function. But in our case, we could communicate each other with controller. we just need a controller that alters element's name before ngForm directive is called.  So for this we have new directive A5.

testApp.directive("testA5", function($compile){
   
    return {
        priority:101,
        restrict: 'A',
        controller: function($scope, $element, $attrs){
            if ($element.controller("form")===null){
                console.log("controller: A5-101:NO form ");
            } else {
                console.log("controller: A4-101: YES form");
            }
            $element.removeAttr("data-test-a5"); //do not remove if we have link function
            $element.removeAttr("test-a5");
            $attrs.$set("name","test");
        },
        link: function(scope, element, attrs){
            if (element.controller("form")===null){
                console.log("\t link:A5-101: No form");
            } else {
                console.log("\t: link A5-101: YES form");
            }
        }
    };
});


This new directive move the name change to controller. It has a higher priority than form. So when it comes to form directive, the name is ready. This solution is better than previous one since we do not change any compilation flow


46 comments:

  1. Excellent I love the posts here, very helpful for developers in the their application development....
    Angularjs online Training

    ReplyDelete
  2. nice posts..
    ]
    Big data training .All the basic and get the full knowledge of hadoop.
    Big data training


    ReplyDelete
  3. Big data and data warehousing related information is always updated to me at hadoop online training in hyderabad. Nice insight on the topic refer the details at
    hadoop online training

    ReplyDelete
  4. I have read your blog its very attractive and impressive. I like it your blog.

    Angularjs Online Training Angularjs Training Angularjs Training Angularjs Training in Chennai Angularjs Training in Chennai

    ReplyDelete

  5. I like your post very much. It is very much useful for my research. I hope you to share more info about this. Keep posting!!
    Best Devops Training Institute

    ReplyDelete
  6. Thanks for updating this quality stuff. Treasurebox always provide you quality stuff for your home and garden.
    We will also provide you outdoor furniture with home delievery.

    ReplyDelete
  7. The article is very interesting and very understood to be read, may be useful for the people. I wanted to thank you for this great read!! I definitely enjoyed every little bit of it. I have to bookmarked to check out new stuff on your post. Thanks for sharing the information keep updating, looking forward for more posts..
    Kindly visit us @
    Madurai Travels | Travels in Madurai
    Best Travels in Madurai
    Cabs in Madurai | Madurai Cabs
    Tours and Travels in Madurai

    ReplyDelete
  8. Excellent Blog. I really want to admire the quality of this post. I like the way of your presentation of ideas, views and valuable content. No doubt you are doing great work. I’ll be waiting for your next post. Thanks .Keep it up!
    Kindly visit us @
    Luxury Packaging Box
    Wallet Box
    Perfume Box Manufacturer
    Candle Packaging Boxes
    Luxury Leather Box
    Luxury Clothes Box
    Luxury Cosmetics Box
    Shoe Box Manufacturer
    Luxury Watch Box

    ReplyDelete
  9. Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
    best workday studio online training

    ReplyDelete
  10. We as a team of real-time industrial experience with a lot of knowledge in developing applications in python programming (7+ years) will ensure that we will deliver our best in python training in vijayawada. , and we believe that no one matches us in this context.

    ReplyDelete
  11. Hello Admin!

    Thanks for the post. It was very interesting and meaningful. I really appreciate it! Keep updating stuffs like this. If you are looking for the Advertising Agency in Chennai | Printing in Chennai , Visit Inoventic Creative Agency Today..

    ReplyDelete
  12. This is a wonderful article, Given so much info in it, Thanks for sharing. CodeGnan offers courses in new technologies and makes sure students understand the flow of work from each and every perspective in a Real-Time environmen python training in vijayawada. , data scince training in vijayawada . , java training in vijayawada. ,

    ReplyDelete
  13. Nice to see this BLOG..keep updating More infromation Digital Lync offers one of the best Full Stack training in Hyderabad with a comprehensive course curriculum with Continuous Integration, Delivery, and Testing. Elevate your practical knowledge with quizzes, assignments, Competitions, and Hackathons to give a boost to your confidence with our hands-on Full Stack Training.
    web development courses
    full stack developer course
    full stack developer course in hyderabad
    web development courses in gachibowli
    front end developer course
    full stack developer course with placement

    ReplyDelete
  14. Thanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
    servicenow online training
    best servicenow online training
    top servicenow online training

    ReplyDelete
  15. It's very useful article with inforamtive and insightful content and i had good experience with this information. We, at the CRS info solutions ,help candidates in acquiring certificates, master interview questions, and prepare brilliant resumes.Go through some helpful and rich content Salesforce Admin syllabus from learn in real time team. This Salesforce Development syllabus is 100% practical and highly worth reading. Recently i have gone through Salesforce Development syllabus and Salesforce Admin syllabus which includes Salesforce training in USA so practically designed

    ReplyDelete
  16. I just got to this amazing site not long ago. I was actually captured with the piece of resources you have got here. Big thumbs up for making such wonderful blog page!
    AWS training in chennai | AWS training in anna nagar | AWS training in omr | AWS training in porur | AWS training in tambaram | AWS training in velachery

    ReplyDelete