Multiple Angular applications on DNN
Placing multiple Angular applications on DNN
In this post I’ll guide you step-by-step through the development of DNN modules with Angular.
Before you continue, I want you to know that this is still a work in progress and is not the perfect solution, but it already solves a few problems. For instance we won’t be able to place the same Angular application on the same DNN page multiple times. This is an Angular related issue and there is already an issue report: https://github.com/angular/angular/issues/16930
So, if you are ok with that for now, than this is the right article for you!
For the examples in this post I use:
- Angular CLI 1.6.8
- Angular 5.2.2
- DNN Community Edition 9
Creating the first Module in DNN 9
This part is going to be the most boring because is all about configuring DNN module. If you already know how to develop a DNN Module you can skip it.
1. Create a new module with C# DAL2 SPA template:
2. Fill up the information and press ok. These infos will be stored in your .dnn manifest file:
Now we need to clean-up this project…
Delete the following folders:
- Documentation
- Providers
- Scripts
- Services
- App_LocalResources
- Components
Delete the following files:
- Edit.html
- Settings.html
- License.txt
- ReleaseNotes.txt
- View.html
- module.css
Now you ask yourself? What? This guy deleted everything!!!
Don’t worry! The point here is only to keep the project as lean as possible for this article, just to understand the concept behind connecting Angular with DNN.
Make sure your DNN manifest looks like that:
I also had to update the ModulePackage.targets
file:
In the end, your solution should look like that:
Generating the first Angular application
In the beginning of this post, the first image shows the location where the DNN module was created, in my case was: D:\Projects\DNN9
Under DNN9 create a folder called Apps. This is how it looks like:
1. Create a new app under Apps:
ng new first-app
2. Use for every Angular app a different tag name for the root element, i.e:
instead of <app-root></app-root>
use <first-app></first-app>
3. Clean up the index.html
to have only the root element <first-app></first-app>
4. Now we need to target our DNN Module. To do that we must tell Angular CLI to copy the distribution files generated via ng build
to our module folder DNN_Module_1 (Attention: I use dist as subfolder).
We do that by changing the outDir
value in the .angular-cli.json
:
"apps": [{
"root": "src",
"outDir": "../../DesktopModules/Modules/DNN_Module_1/dist",
...
]...
5. As we changed the outDir
we also need to change the deploy URL, otherwise DNN won’t find the bundles:
ng build --deploy-url DesktopModules/DNN_Module_1/dist
6. Update the DNN_Module.dnn
<controlSrc>DesktopModules/DNN_Module_1/dist/index.html</controlSrc>
Compile and reinstall the module and you should be able to see the Angular DNN Module:
Please check also the list of parameters of ng build
that might be helpful for you to optimize the file distribution to the DNN Module:
Ok, now what? We have only one Angular app inside DNN.
Create a new DNN Module with Angular, install it and this is what happens:
BOOM!!! Zone already loaded! But what is Zone?
In short Zone.Js is a JavaScript library used by Angular to control the change detections. If you want to understand it better, here some links:
https://angular.io/api/core/NgZone
https://angular-2-training-book.rangle.io/handout/zones/
https://medium.com/@MertzAlertz/what-the-hell-is-zone-js-and-why-is-it-in-my-angular-2-6ff28bcf943e
There are two ways I know we can solve this:
- use
ngZone: ‘noop'
— not recommended otherwise you have to control change detection yourself and this is not fun - comment out
zone.js
inpolyfills.ts
— that is my preferable and I’ll explain why
Commenting out zone in the polyfills and keeping ngZone in default mode will give us the flexibility to reference zone.js
in the portal skin, which is not bad at all. Zone is going to be loaded only once, saving for us a few Kbytes.
TL;DR
- You can run multiple different Angular apps in the same DNN Portal, but not the same instance of the same Angular app multiple times (https://github.com/angular/angular/issues/16930)
- You must include
zone.js
in the DNN Portal Skin and comment outzone.js
from thepolyfills.ts
- Use different tag names for every Angular application to avoid conflict