Products

Solutions

Learn More

Partners

Community

Blog

About

DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.


JavaScript MVC 2.4 - Understanding a real AngularJS App-Initialization

This is a part of my second short series about JavaScript MVC Frameworks. In this part I'll show you a real-life AngularJS App (albeit a simple one) and explain all relevant parts so that you can create your own. I've split it into multiple posts - this one explains how an Angular-App is initialized. You should understand this, because the magic is there, and if something doesn't work, it helps to know what happens behind the scenes.

If you have not already read the previous parts, I would highly recommend you start there. Especially the post about the AngularJS App-View contains vital information + prerequisites so you can try all this code directly in your DNN.

Prerequisites

To learn AngularJS you will have to get your hands dirty. So go ahead and install DNN with 2sxc as explained in this post  and install this demo-App containing all the code explained here.

Initialization Overview

This is a rough overview so you see the big picture, before we go into the details.

  1. AngularJS manages all modules, and will ensure that they are loaded in the right sequence - because each module will say what things it depends on - and Angular will manage that.
  2. The inline-Javascript (boostrap…) will use the target-placeholder in the HTML and set the App to be there. It will make sure the right things (like the controller) get attached, and optionally call some init-commands.
  3. The controller will then be created and return the data in the $scope (more or less the ViewModel)
  4. When the scope is ready, the data will be bound to the template

Let's look at this sequence a bit more in Detail

Part 1: AngularJS Dependency Management

Angular is in charge of ensuring that all dependencies are ready for each component (called a module). It does this by

  1. Knowing which parts exist and MAY be relied upon (each "thing" must register itself so it can be used)
  2. Knowing which parts ARE relied upon (so each thing must say: I will need a,b and c)
  3. In addition, any parameters with a known name (pre-registered or typically with the $) will automatically be provided by AngularJS. So simply by saying "this method needs $window" it will automatically receive $window.

Here you can see this in the controller...

...and in the HTML

The code is mostly self explanatory. The one detail I would like to point out is the dependency declaration: at the end of the long statement you see a ["DemoFaqAppAdvanced"] which again tells Angular that it has to load that DemoFaqAppAdvanced before trying bootstrapping (loading) the app.

Part 2: Defining the App in the HTML

This happens with the on-ready JS code. Since we cannot assume an SPA (Single Page Application) but must expect an MAP (Multiple Apps per Page), we should never use ng-app but instead use the following procedure:

  1. always put the ModuleId somewhere in the App-Container (the div-tag which will host the App)
  2. always pass it into the controler-initializer with $attrs
  3. and always use that in the controller...
  4. ...and put it into the $scope for re-use

This is what it looks like in the HTML...

...and in the code

 

Part 3: Controller Initialization

Now that Angular loaded the controller (because of the dependency) and started the App with this, it will initiate the controller. Note the $attrs which we need to determine the ModuleId passed in the HTML-attribute data-moduleid. Again, it's automatically connected by Angular. 

The controller then initializes the $scope (+/- the viewmodel) and then hands control back to AngularJS.

Part 4: Data- / View-Binding

Once the $scope is filled, it reports this by saying $scope.$apply() - this will tell AngularJS that something changed, and that data-binding would be a good idea sometime in the future. That's right: Databinding does not happen right then and there! This is a great feature in AngularJS. We used to work with knockoutJS which binds data automatically - this required us to write much longer code (using observables) and killed browser performance, because every change tried to rebuild the view - again requiring workarounds. Angular automatically detects binds after specific events like clicks and more, but won't auto-bind if data is added "secretly". Because of this we tell AngularJS that it should $apply again.

Summing it up

AngularJS does a lot for you behind the scenes, making it easier to develop according to best practices. But you must understand what it does to leverage the power of AngularJS. I hope you love it as much as we do :).

You must get your hands dirty!

Reading this won't make you smarter if you don't try it yourself. Just use 30 minutes to download the App, make some adjustments (like adding fields or changing the JS-effects). That way you'll get smart really fast!

 


With love from Switzerland,
Daniel 

Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 600 DNN projects since 1999. He is also chief architect of 2sxc (2SexyContent - see forge), an open source module for creating attractive content and DNN Apps.

Comments

wilby K
Daniel, I really love your work and the power of angularjs. Could you also give examples of using OR best way of implementing angularjs in a dnn module development template, eg., christoc OR InspectorIT/DNN-Module-Template. How can we use angularjs in those templates. And what is the most effective way. I als hope that somebody can post (url) of a good example. And I hope that Jonathan Sheely give us some examples.
wilby K Tuesday, November 25, 2014 10:47 AM (link)
2sic Daniel Mettler
Hi Wilby
Because the future of .net is so different than the current module-system in DNN, I have some difficulty providing a good example for those. Reason: In the near future (IMHO) there will be no more precompiled DLLs on the server, no more WebControls.

So the future has open-sourced (literally: with source) WebAPIs (on-the-fly-compiled) which deliver the data to the AngularJS App. And all operations (like save, edit, etc.) will also be performed through such WebAPIs.

We just finished this setup for 2sxc (V. 6.4.2 beta offers exactly this setup). Since we plan to go stable next week, I'll see if I can provide good examples for this. But it's not the classic DNN-Module like you've seen - it's more the way DNN-Modules will be built in DNN 8.
2sic Daniel Mettler Tuesday, November 25, 2014 11:47 AM (link)
2sic Daniel Mettler
Just to correct one minor mistake: there will be precompiled DLLs on the server - namely those of the "environment". So of course .net DLLs will exist and DNN will probably be fully precompiled. But the final layer of service - the custom stuff - will only be on-the-fly compiled.
You can discover more about this if you research the new open-source .net on-the-fly compiler called Roslyn by Microsoft.
2sic Daniel Mettler Tuesday, November 25, 2014 11:49 AM (link)
Scott Wilkinson
Daniel,

I am currently working on an Angular module demo for DNNHero. I got a lot from your blog on this subject. One thing I am trying to determine is the best practice way of accessing DNN framework services from Angular. I have a working example using the $http module to call the WebAPI service from the controller. What I prefer would be to create an angular service or factory that handles the service calls for my controller. I just need to figure out the best way to pass the moduleID and moduleName into the service/factory instead of the controller. Then I can call the service/factory methods from my controller.

Like you, I am trying to encourage developers to shift from webforms to MVC. Until we get to DNN7.5, developing a module with Angular/WebAPI services represents a step toward that transformation to remove dependencies on the webforms layer.
Scott Wilkinson Saturday, November 29, 2014 10:30 AM (link)
2sic Daniel Mettler
@Scott: glad to hear that more or "on the mission" :)

The way I see it (but bear with me that I never programmed a service before since i'me more the consultant and can't spend as much time coding as i would like to...) the service is a singleton pattern. Meaning it could never "remember" the module IT at initialization, because otherwise all instances would have the same ModuleID. So I'm guessing the module-id would have to be handed in for every single request.
2sic Daniel Mettler Sunday, November 30, 2014 9:36 AM (link)
Jordan
you are right Daniel,

the services are created as application singletons. The following documents this:
https://docs.angularjs.org/guide/services
And
https://www.airpair.com/angularjs/posts/angularjs-tutorial#6-services-and-factories

So the module id must be per request.
Jordan Wednesday, December 03, 2014 12:04 PM (link)

Comment Form

Only registered users may post comments.

NewsArchives


2sic Daniel Mettler (133)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (25)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (7)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (270)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (164)
William Severance (5)
DNN Launch Webinar
REGISTER NOW
DNN Launch Webinar
REGISTER NOW
DNN Launch Webinar
REGISTER NOW