Written on 9/17/2014 in Web development

Requestor part 2


NancyFx AngularJS

In part 2 of the Requestor series, I will be talking about the setup. I created the following project structure:

Requestor
>-- css
>-- js
>>---- angular
>>---- controllers
>>---- modules
>>---- services
>-- nancy
>-- views
>>---- Requestor

Easy enough. 'css' will hold all style related content (images, css files, fonts). 'js' will hold all javascript files. This is divided into 'angular'1 holding angular lib files, 'controllers', 'modules' and 'services' holding respectively angular controllers, modules and services. 'nancy' will hold NancyFx configuration and the routing module(s). 'views' speaks for itself, like all previous ones actually did too.2 This was my first angular project so this structure was mostly guessing how I could best manage the files. If I had to set it up right now, I would do it like this:

Requestor
>-- css (CSS)
>-- js (JavaScript)
>>---- lib (all javascript libraries)
>>>------ angular
>>---- app (all angular related stuff)
>>>------ controllers
>>>------ modules
>>>------ services
>-- nancy_config (C#, nancy configuration classes)
>-- nancy_modules (C#, nancy modules for answering requests)
>-- views (HTML)
>>---- Requestor

For the views I could use another NancyFx default. The Super Simple View Engine(SSVE) is a basic view engine that allows for functionality like master pages, sections, partials, iterators, ... But nothing too fancy. It is easy to use and very fast. I used a master page for general layout:

<!DOCTYPE html>
<html lang="en" ng-app="Requestor">
    <head>
        <!-- meta's and css links stripped -->
    </head>
    <body ng-controller="mainController">
        <!-- menu stripped -->

        <div id="MainContainer" class="container-fluid">
            <div class="content-container">
                @Section['Content'];<!-- SSVE Content section defined -->
            </div>
        </div>
        <script src="/js/jquery-1.9.0.min.js"></script>
        <script src="/js/bootstrap.min.js"></script>
        <script src="/js/underscore.js"></script>
        <script src="/js/angular/angular.js"></script>
        <script src="/js/modules/autocomplete.js"></script>
        <script src="/js/modules/angular-requestor-main.js"></script>
        <script src="/js/services/PersistenceService.js"></script>
        <script src="/js/services/SettingsService.js"></script>
        <script src="/js/controllers/mainController.js"></script>
        @Section['Scripts'];<!-- SSVE Scripts section defined -->
    </body>
</html>

It's easy to see an immediate downside of NancyFX's SSVE. I intentionally left in the scripts because I was not able to find any easy-to-use bundling and minification module for Nancy. There were a few mentioned but most of them needed the Razor view engine to function properly.3 I have not taken a close look into this matter yet, so I apologise if there is an easy way but it was not clear to me.

Anyhow, I put the 'ng-app' directive on the 'html' tag. This will initialise an angular app with 'Requestor' as name and defines the root scope. This root scope is like the Javascript global scope but in the angular namespace. It's the outside layer of scopes.

I also added an 'ng-controller' attribute on the body. AngularJS controllers have a scope on which variables can be declared. They can then easily be used in directives. These scopes can be nested. You can access variables defined in the mainController scope in a nested controller. So by declaring a mainController in my master page, I am able to declare variables on it that I can use in all views using this master page. More information about how angular scopes work can be found on this wiki.

The actual app page looks like this:

@Master['master.sshtml']<!-- define master page for SSVE -->
@Section['Content'] <!-- content section -->
<div id="req-container" class="row-fluid">
    <div id="req-left-container" class="span2" ng-show="isLocalStoragePossible()" ng-controller="requestStorageController">
    <!-- The left container will hold the history and request collections -->
        @Partial['partials/requestStoragePartial.sshtml']
    </div>
    <div id="req-right-container" ng-class="isLocalStoragePossible()?'span10':'span12'" ng-controller="requestorController">
    <!-- The right container will hold request configuration and responses -->
        @Partial['partials/requestorPartial.sshtml']
    </div>
</div>
@EndSection
@Section['Scripts']
<!-- page specific scripts stripped -->
@EndSection

The partials are HUGE4. But they're actually well organised. I will provide a full solution, so if you want to check them, be my guest. I styled the pages a bit and came up with the following:

Requestor app screenshot

I'll let that sink in for a while, mostly because it's cluttered and UX- unfriendly.

Newer Older Top
blog comments powered by Disqus