X
dnn.blog.
Back

DNN module development with AngularJS (Part 1)

What should you expect from this blog series ?

This blog series should set you in the position to start DNN module development with Angular even if you haven't done a module for DNN yet. So we will start with an empty project in Visual studio and build it up step by step. I plan to guide you through all these steps. But beware, this is no Angular course! I will not explain all the stuff that is involved in full detail because that would fill a book and is way too much for a blog like this, but where possible I'll provide you some links with further information to the corresponding topic. First we will start with a DNN 7 style Angular module using standard View.ascx that is able to run in DNN 7 and later we will convert this to a SPA module type for DNN 8.

My personal Angular history

I started my carreer developing desktop applications with Visual FoxPro which was similar to VB6. You create a form, throw controls on it, doubleclick on a button, write code what should happen if you click the button, run it and it works. VFP was outdated one day and I started to code in Visual Studio. Winforms was a natural learning path for me and the paradigma was not too different so this worked OK for me. But everywhere it whispers : "XAML, MVC, WPF, Silverlight..." and a dozen new technologies for creating desktop applications came up and nobody knew which one would win. And I couldn't decide what to learn next either. I tried a little bit WPF but it was awful. Throwback in productivity 500%. After some more tries I totally stopped developing desktop application and decided to go the web way which seems to be the future for me (for heavens sake I was right!). But holy crap, this was not easy! I had to learn that every click on a button first has to go to the server and the result has to be rendered on the server and send back trough the wire and the state of controls must be sent back and forth - you all know this server side stuff! But I learned it with a lot of obstinacy and created some really sophisticated DNN modules over the time. Nevertheless it bugs me that the whole thing feels so stiff and slow and I started to look at client side development. Naturally for me I started with Knockout which came out-of-the-box with DNN. Suddenly it feels a little bit like magic again, like in the old desktop days. You create some UI with HTML and define which data go to which control, bind the data to your UI and BÄM! its working all alone in the browser! I was happy and started to use it extensively. Felt very good and the user experience was great because of the responsiveness and speed. There are some aspects in Knockout that makes programming a little bit laborious (observables...) but I got familiar with them. Finally at DNNConnect 2015 in France I saw a session from Daniel Mettler (2sic) about Angular module development and I realized that this is really impressive. Its not only about databinding like Knockout, it does the whole thing! And its easy to write and understand! And modular! Need some diagrams in your app ? Go for a angular diagram library in the web, download the code and throw it into your app and simply use it. I really love this because after all those years I can feel the easyness of programming like in former VFP times again. I hope I can ignite this fever in you too with this blog series!

Some fundamentals about SPA architecture and Angular

In clientside programing paradigma, the whole page is rendered only once and all later actions are done by AJAX calls questing for data and sending data to the server and manipulating the existing page HTML DOM via javascript. Thats why they are called SPA (Single page applications)

Angular JS – often named simply as Angular – is an Open-Source-Framework built by Google Inc. With Angular it is possible to write Single-Page-Applications (SPA) with HTML5 and Javascript based on the Model-View-ViewModel (MVVM) pattern. Angular implements MVVM to create a bidirectional binding between HTML and JavaScript. And it also structures the fundamental architecture of web applications with MVC.

Normally when you develop clientside appications you have to develop two parts. The first part is the frontend side with all the HTML, CSS, Javascript und Images. This is normally done with your preferred web editor and some imaging software. The second part is optionally and depends on where your data comes from. If you develop a map application and all your information comes from google maps you don't need a server component. But if you need to save and retrieve your own data, you need a server part too. This part is often built with tools like node.js or other backend technology. In a DNN module we have these two parts bound together as one module using DNN APIs like DAL2 (Data Access layer using PetaPoco framework), WebApi for the "server" part and WebUserControls (ascx) plus Html,Css etc. for the "client" part.

If a user hits an Url in his browser to a DotNetNuke installation, DNN generates a page containing your module Html and Javascript and posts this back to his browser.

Now the (Angular-)Javascript in the browser starts to run (e.g. when loading of the page is finished or the user hits a button) and makes an Ajax call to the server. This call walks through a few layers on server side shown here in this image:

Angular registers the button click and invokes an REST AJAX call to the server. On server side this call is received by the WebAPI which converts the REST call to a method call to the controller with typed parameters. In the controller the method call is converted by PetaPoco to pure SQL that quests the database and returns the data. The controller takes the data and converts them back to an object or IEnumerable and returns them to the Web API. In this layer they are converted into json and sended back to the browser where finally Angular receives them back and automatically actualizes the Html depending on the action.

 

The benefits of using Angular

Two-Way-Databinding

Two-Way-Databinding is meant as synchronisation of the data between View and Model. If we change the data in the view, the changes are automatically transferred to the datastructure in the model. If we change the data in the modell, automatically the display in the view changes too.

Extensability and Readability of HTML

One of the most outstanding features of the framework is the possibility to create user defined HTML tags and attributes. These tags and attributes could be used then in your application as standalone, reusable extensions. Instead using a lot of deep nested div elements a better and easier to read code takes place. See the following example:

<image-uploader accepted-type="image/png" enable-drag-drop></image-uploader>
Abstraction of low level operations

When we use jeury we have to do always the same things: DOM selection and manipulation. When we had inserted a new element in an array, we use jquery to find the correspondig list in the DOM (selection) and then we need to insert the new node there (manipulation). In Angular we only describe that we want to link the list in the DOM with the array. From this point on Angular synchronizes everything automatically. The philosophy of Angular is, that a web application changes its representation only as a result of changes in the corresponding viewmodel. Direct manipulation of the DOM is in most cases unwanted! For this purpose Angular makes use of a lot of predefined directives, all beginning with the prefix ng- (ng-click, ng-href, ng-...).

Dependency injection

For the wiring of the components angular has a built-in dependency injection container (DI). Instead of binding the components statically, one registers them as standalone, isolated modules and describe their dependencies declarative. Angular solves these afterwards automatically. Software development and testing could be simplified considerably.

Testability

The original author, Miško Hevery has placed great emphasis on testability. This refers not only to the very good test coverage in the framework itself. Even the developer himself should be able to test his application easy. If you stick to the Angular way, tests are really very easy to write .

Including Angular into your module

There are two different approaches to get the Angular libs (and other javascript libraries) into your module. The first one is what most developer do: Download the code and bundle it with your module. But this is not the best way to do things because it becomes problematic when two modules on a page use the same library: Its getting injected two times into the page and this could lead to errors. And you lose the benefits of the Client Dependency Framework in DNN which has the build-in capability of minifying and merging js files to reduce http requests.

The second approach is making usage of DNN Javascript Library packages. These could be installed into DNN as any other module, skin or whatever. There are a lot of ready made Javascript libraries in the DNN Forge (search by exact tag "JavaScript Library") from Brian Dukes (Engage Software). Unfortunately there are no Angular libs so we had to build them for ourselves.

What you need to know is that one library can hold only one js library, normally in the minified version. You can attach corresponding files like css, map and unminified version of the js, but it is not possible to have multiple other js files (for example for i18n = localization) also packaged into this library - they are not loaded! You need to build another package.

A Javascript Library package consists typically of the following components:

1.) Manifest file (e.g. angular.dnn ) 2.) Javascript File (e.g. angular.min.js) 3.) Html Description file (shown at installation time) (e.g. changes.htm) 4.) Image File (min. 128px square png file) for display in extensions (e.g. extension.png) 5.) License file (Html allowed) (e.g. license.htm) 6.) Zip of additional Resources (e.g. resources.zip)

These components should be zipped together into one file (e.g. angular_1.4.5.zip). Now you are able to install this zip file like any other package in host-Extensions.

This is what the manifest file should look like for Javascript libraries:

<dotnetnuke type="Package" version="5.0">
  <packages>
    <package name="AngularJS" type="JavaScript_Library" version="1.4.5">
      <friendlyName>AngularJS</friendlyName>
      <description>AngularJS is what HTML would have been, had it been designed for building web-apps.</description>
      <iconFile>Resources/Libraries/AngularJS/extension.png</iconFile>
      <owner>
        <name>Google</name>
        <organization>Google</organization>
        <url>http://www.google.com</url>
        <email>support@google.com</email>
      </owner>
      <license src="LICENSE.htm" />
      <releaseNotes src="CHANGES.htm" />
      <azureCompatible>true</azureCompatible>
      <dependencies />
      <components>
        <component type="JavaScript_Library">
          <javaScriptLibrary>
            <libraryName>AngularJS</libraryName>
            <fileName>angular.min.js</fileName>
            <objectName>angular</objectName>
            <cdnUrl>https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js</cdnUrl>
            <preferredScriptLocation>PageHead</preferredScriptLocation>
          </javaScriptLibrary>
        </component>
        <component type="JavaScriptFile">
          <jsfiles>
            <libraryFolderName>AngularJS</libraryFolderName>
            <jsfile>
              <name>angular.min.js</name>
            </jsfile>
          </jsfiles>
        </component>
        <component type="ResourceFile">
          <resourceFiles>
            <basePath>Resources\Libraries\AngularJS\01_04_05</basePath>
            <resourceFile>
              <name>Resources.zip</name>
            </resourceFile>
          </resourceFiles>
        </component>
        <component type="File">
          <files>
            <basePath>Resources\Libraries\AngularJS</basePath>
            <file>
              <path></path>
              <name>extension.png</name>
            </file>
          </files>
        </component>
      </components>
    </package>
  </packages>
</dotnetnuke>

For more information about DNN manifest files, see: http://www.dnnsoftware.com/wiki/manifests

Learning Angular

In the next part of this blog series we will start making our hands dirty. In the mean time I'll leave you some resources that helped me a lot getting started with Angular.

The first one is a free online course by Code School "Shaping up with Angular". Its an interactive course where you listen to some webcasts and after each lesson you get some quests to solve online - very helpful!

The second one is the Angular Style Guide by John Papa. In my opinion a "must read" because he defines a lot of patterns that makes your code more readable and structured. And he is an advocate for the "controllerAs View Syntax" avoiding the $scope syntax which is definitely the better and more robust syntax style ($scope => dll hell for Angular).

DNN Hero webcasts by Scott Wilkinson about Advanced Module Development. These helped me a lot to get started with Angular in DNN modules. This is a payed resource but it is really worth it!

And, last but not least, not to forget the Angular Homepage full with Youtube videos, tutorials, courses, case studies, guides, references etc.!

Back
Total: 6 Comment(s)
Kurt Amstutz
Torsten - Many thanks for taking the time to document your steps for integrating Angular with DNN. I hope to give them a test drive soon. I too have made the jump to client side module development (mostly using Clint Patterson's tutorial series) - ajax calls, no server controls and lots of javascript. I'm really only using DNN for the CMS features of user and page administration, as well as localization (English/German BTW). Thanks again for your work.
Monday, December 19, 2016 · reply ·
Peter
Torsten - Thank you very much for creating this series on AngularJS and DNN. These are extremely useful! You've worked in a lot of information into these. I was about to try my hand at emulating this from scratch and you've given me a wonderful foundation to work off of. This is one of the only such tutorials I've found (of use) on this combined topic; which I would think would be a very common combination of related technology and techniques. I love that you did not inject any third party helpers into this, just nice straight forward examples using what is natively available in DNN and asp.net. Thanks again. - Peter
Thursday, December 22, 2016 · reply ·
Monika
Torsten- really useful article.
Wednesday, February 8, 2017 · reply ·
Marco
Great Article! I can't understand why there is not a official guide for SPA DNN Module & Angular (now 2.0)....
Friday, April 7, 2017 · reply ·
H. Tom Thomas
Thanks very much for the excellent tutorial. Your efforts are very appreciated. I hope you get something out of it besides adoration from grateful coders! How about a quick posting on how Angular4 and the CLI change the implementation?
Wednesday, June 14, 2017 · reply ·
Gus
Great tutorial. Clearly a lot of work went into this. Thanks. I have an issue though. Downloaded project and I get this error loading the solution in VS 2017: error : The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets" was not found. Also, tried to find "Microsoft\VisualStudio\v14.0\WebApplications\Microsoft.WebApplication.targets" in the fallback search path(s) for $(MSBuildExtensionsPath32) - "C:\Program Files (x86)\MSBuild" .
Tuesday, July 18, 2017 · reply ·

about.me.

Torsten WeggenMy name is Torsten Weggen and I am CEO of indisoftware GmbH in Hanover, Germany. I'm into DNN since 2008. Before this, I did a lot of desktop stuff mainly coded with Visual Foxpro (see http://www.auktionsbuddy.de). 

I'm programmer, husband, father + born in 1965.

Please feel free to contact me if you have questions.

Latest Posts

DNN module development with AngularJS (Part 6)
12/16/2016 7:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 5)
12/16/2016 6:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 4)
12/16/2016 5:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 3)
12/16/2016 4:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 2)
12/16/2016 3:00 AM | Torsten Weggen
DNN module development with AngularJS (Part 1)
12/15/2016 7:19 AM | Torsten Weggen
Blogging in DNN with Markdown Monster by Rick Strahl
11/27/2016 1:14 PM | Torsten Weggen
Creating a global token engine
11/18/2016 10:25 AM | Torsten Weggen
DnnImagehandler - Hot or not ?
2/21/2015 11:52 PM | Torsten Weggen
Rapid Module Development Part 2 - The multilanguage thing…
4/7/2014 7:32 PM | Torsten Weggen

My Twitter

Torsten Weggen 7/22/2017

RT @CBPSC: Ventrian modules now free on Github! https://t.co/aKLeZawVHN #DNNCMS https://t.co/x6mhie382I

Torsten Weggen 5/24/2017

RT @WaldkauzFolk: ++ Waldkauz goes W:O:A 2017 ++ Der Wahnsinn - Wir sind in diesem Jahr beim großartigen Wacken Open Air mit... https://t.…

Torsten Weggen 4/25/2017

RT @WaldkauzFolk: "A magical pagan folk release getting a lot of inspiration of myth, legends and tales from countries all over... https://…