This project is read-only.

Angular For Model

This is an extension to ASP.NET MVC that creates a tight and smooth integration between MVC on the server and AngularJS MVC on the client.

Goals

The project consists of several parts:
  • A set ot attributes to decorate ASP.NET MVC controllers and make connections to Angular controllers
  • A set of extensions that create forms using EditorFor and EditorForModel that are aware of Angular's attributes and Bootstrap's styles
  • Angular directives for better integration with JQuery validation

Usage

The primary idea is an automation process for creating forms based on models decorated with a bunch of attributes. This makes the model to a single point of change in the project and hence easier to maintain.

Once we have a sophisticated model we can create views out of it without care to much about HTML and everything around it. Especially, we can avoid digging deeper into HTML, JavaScript frameworks, Bootstrap CSS, and finally AngularJS. There is still some work to do for creating special controller functions, but the whole infrastructure is created automatically.

To start, we decorate an MVC Web API controller with

[NgDataContext(typeof(DemoController), "DemoPortal/api")]

This creates a data context class in JavaScript that supports the angular controllers.

Each method must be decorated like this:

[NgDataContextFunction]
public ActionResult GetProjects() {
      // we create some fake projects to let the UI running
      List<EaProject> result = new List<EaProject>();
      result.Add(new EaProject { Description = "Angular JS", Id = 1, IsPublished = false, Name = "NG", StartedAt = DateTime.Now });
      return JsonList(result, Math.Min(5, result.Count), JsonRequestBehavior.AllowGet);
}

So, that's all we need to have an API.

Now, we create forms. We start with regular, Razor enabled MVC forms. These forms are supported by regular MVC controllers. However, these controllers are quite stupid, as the hard work is in the Angular controllers. But we benefit a lot from this duplication of controllers.

See the beginning of such a controller:

[NgController]
public class ProjectController : AngularJsController {

    [NgController("~/Views/Project/js/index.js")]
    public ActionResult Index() {
      return View();
}

NgController is the trick to create and place the Angular stuff.

A view looks like this:

@using Mvc2Ng.Web.UI.Areas.EasyAuthorPortal.Extensions
@model EditProject
<section class="mainbar" data-ng-controller="editproject as vm">
  <section class="matter">
    <div class="container">
      <div class="row">
        <div class="widget wgreen">
          <div data-cc-widget-header title="{{vm.title}}"></div>
          <div class="widget-content user">
            <p>
              Fine tune your project, invite contributors, and pre-set publishing options.
            </p>
            <form role="form" data-ng-submit="editProject()">
              @Html.AngularEditorForModel()
              <button type="button" data-ng-click="cancel()" class="btn btn-danger pull-left">Cancel</button>
              <button type="submit" class="btn btn-default pull-right">Save</button>
            </form>
          </div>
        </div>
        <div class="panel panel-warning" data-ng-show="!vm.isValid">
          <!-- Default panel contents -->
          <div class="panel-heading">Panel heading</div>
          <div class="panel-body">
            <p>{{vm.validationSummary}}</p>
          </div>
        </div>
      </div>
    </div>
  </section>
</section>

The helper AngularEditorForModel creates the whole form as we need it to support the controller.

To make it working some restrictions apply to paths, naming, and bundling. The upside is a drastic improvement in development speed and reliabilty.

Next Steps

The next version will contain several more helpers that automate the HTML - Bootstrap aware - for the rest of the form. Especially it addresses the creation of verbose containers and panels.

Last edited Jan 21, 2014 at 10:19 PM by joergisageek, version 6