- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-13-2015 11:58 AM
Has anyone successfully used routing within an Angular UI? I'm working with a BootStrap navbar, and trying to define content using routing (ng_route). Having a little trouble, but before I spend too much time with this approach, wanted to checkin to see if this is even possible within ServiceNow.
Thanks in advance for any advice/direction!
Solved! Go to Solution.
- Labels:
-
User Interface (UI)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2015 07:36 AM
Hi Mitch,
It is definitely possible. The best approach I have found is to use a processor to handle the views because UI Pages and other endpoints add text to any template you would send through. So your ng-route when statement will point the templateUrl to the processor. The processor will then return the view html template. Please feel free to ask any questions on this.
Kind regards,
Travis
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2015 10:39 AM
There are two options that I can see that will meet your requirements and maintain a solid architectural design, I definitely agree that your 3 process paths should use separate controllers. Angular controllers can be tough to unravel once they get complex enough, better to design early and save yourself the pain later.
My recommendation is to go with Option 1 and refactor if you find a need UNLESS you are comfortable doing extensive troubleshooting across UI Pages, UI Macros, UI Scripts, ServiceNow Processors, AND AngularJS. Option 2 can get pretty hairy.
Option 1: Separate UI Pages for each page/process
Advantages: This is probably the easier approach of the two. It allows you to use UI Pages in the known, documented way without any additional complexity. Each UI Page can require AngularJS individually and use the ng-controller attribute. This is probably the easiest way to use AngularJS for its template capability without diving into all the other pieces. Every page contains everything it needs individually (model, view, and controller).
Disadvantages: The main disadvantage is that you require full page refreshes for each link you click, no pretty AJAX magic. Also its easier to cheat the application architecture and use poor AngularJS practices which can cause maintenance headaches later.
Option 2: Using AngularJS Routes
Advantages: You get all the UI/UX magic of AngularJS. If you use the power Angular offers wisely (Services, Controllers, Directives, Routes) this can lead to a great application architecture that is easily maintainable. Everything becomes a component with a single responsibility. You also get a more seamless AJAX based user experience with fewer page refreshes... which with the size of ServiceNow pages can be a HUGE benefit to users with slower connections.
Disadvantages: Without the 1 page - 1 controller architecture, you have to devise a way to manage your Angular components (embedding or dynamic loading). This can get much more complex to build and a bad architecture can eliminate any benefits. The easiest way to get around this is to modularize the AngularJS app using UI Scripts and/or UI Macros (1 UI Script - 1 Controller module | 1 Macro - 1 Angular Template using <script> tag) and then include/embed all the scripts for the application in the UI Page with a g:requires tag. This results in a slower initial load but saves you the pain of dynamically loading routes.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-14-2015 10:44 AM
Travis...thanks very much for taking the time to provide these details...you've set me up for success!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-15-2015 03:00 PM
Hey Travis...is there anything I need to do to make the processor available to the controller in the config block?
My block in the MainController looks like this:
.
.
app.config(function ($routeProvider) {
$routeProvider
.when('/build', {
template: 'buildProcessor',
controller: 'BuildController'
})
.when('/status', {
template: 'statusProcessor',
controller: 'StatusController'
})
.otherwise('/');
});
.
.
I've tried adding '*.do' to the template assignment, but all I get is the literal template value in my <ng-view> block. So on click, the block will contain either the string buildProcessor or statusProcessor instead of the contents of the HTML UI Pages the 'g_processor.redirect' statement points to in the processors.
I can call the processors from the URL (https://<instanceURL>/buildProcessor.do) and the HTML is served up properly, so I'm wondering if their is something I have to do to allow the processors to be called from a controller. (I don't have any Protection Policy settings on the processors).
Also, I'm using Accelerator...I'm going to try to create an Application from scratch and check for any differing behavior, but wanted to check in to see if I was missing something.
Thanks for any advice you might have.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-15-2015 03:25 PM
Hi Mitch,
Within your when object, the template property should contain the actual HTML template, which is why you see the name displayed. What you want to use is the templateURL property. So in your example above, you would want to set it up as:
app.config(function ($routeProvider) {
$routeProvider
.when('/build', {
templateURL: 'buildProcessor.do',
controller: 'BuildController'
})
.when('/status', {
templateURL: 'statusProcessor.do',
controller: 'StatusController'
})
.otherwise('/');
});
Check out the angular documentation on $routeProvider. This link will take you to the route provider's when method documentation, check out the route parameter object: https://docs.angularjs.org/api/ngRoute/provider/$routeProvider#when
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-17-2016 02:59 PM
Hi Travis,
Got a question about an old response you posted. Hopefully you still see it.
I am using the syntax above in my routeProvider, but the UI Macro I am putting in the "templateURL" variable isn't rendering.
The UI Macro I am using contains a single line of HTML. When I hard code an HTML string in the "template" variable, it shows up fine. Am I doing something incorrectly here? I am on Geneva, so not sure if anything has changed since your post.
Your help is GREATLY appreciated!
(function () {
angular.module('rmp.shell', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider
.when('/portal', {
controller: 'Portal',
templateURL: 'test.do'
})
.otherwise({
redirectTo: '/portal'
});
});
})();