Slicing an SPA into several components and use AngularJS - asp.net-mvc

I'm a complete beginner with AngularJS so this may be something completely trivial. I'm building an Asp.net MVC application (really juts delivering insignificant parts) with Web API backend (including login/logout capabilities).
I'd like to use AngularJS in my application. But I have a bit of a dilemma how to slice my page into several sections that somewhat work independently. Let's say this is a simplified skeleton of my page.
Questions
How should I structure my AngularJS parts on my page?
Should I have a single ng-app for the whole page or have several non-nested ones for each individual component on my page?
In case of a single ng-app I expect to have one ng-view that would include Context and Content components.
How about client-side routing with each individual option (single/multi ng-app)?
Is this a viable approach or should I think of Angular differently and structure it differently?
I should likely have separate controllers for each individual component and a single authentication service (communicating with Web API on the server) to provide user authorized items.
What would you recommend?
Bare in mind I'm a complete beginner in AngularJS but am very versed in server side part (MVC and API).

Let me try to address some concerns
Should I have a single ng-app for the whole page or have several
non-nested ones for each individual component on my page?
There can be only 1 ng-app per SPA, so you cannot have ng-app per component. You can have module per component which can be tied into the ng-app related module.
In case of a single ng-app I expect to have one ng-view that would
include Context and Content components.
ng-view would only contain the content of the active view. It does not require to have any menus. There can be something like RootController which is container for overall app. The html would consist of the obvious ng-view and number of ng-include.
Something like
<div ng-controller='RootController'>
<div id="contextMenu"><ng-include src='contextMenuTemplate'></div>
<div id="primaryMenu" ><ng-include src='primaryMenuTemplate'></div>
<div id="secondarMenu" ><ng-include src='secondaryMenuTemplate'></div>
<div ng-view/>
</div>
In your RootController you would have some logic like
if ($route.path) {
$scope.contextMenuTemplate="path1"; //path corresponding to the route
}
Or else you can also create a object map and use that for selecting the templates
var viewTemplates= [{
path:"/home",
contextMenuTemplate:"path1",
primaryMenuTemplate:"path2",
secondaryMenuTemplate:"path3"
}]
This can now be used for selecting templates in ng-include.
How about client-side routing with each individual option (single/multi ng-app)?
Routing happens on the ng-view part only. You select other templates to load based on the primary view. You can also look at ui-router for advance routing stuff.
Update
When authentication and authorization comes into picture both the server and client play their part. Server authenticates and then can use that information for service different templates if the user is authenticated or not, and may on the same url. For example /home/leftnav can server different content based on the authenticated user. Same can be done on Angular side but this behavior can be by-passed as it is just javascript. Same holds true for api calls (using webapi) where server can decided what to send back.
On client side user state can be tracked using a service\factory. A service like UserService with methods\properties like CurrentUser can provide details on the current logged in user and can be injected into any directive, filter, controller which as to make decision based whether and what user is logged in..

Related

Claims-Based Authorization with Angular.JS and WIF

We have an application built with ASP.NET MVC 5.
For that application, we've built several URL-related HTML helpers that act like this:
Imagine there is an anchor that leads to certain URL, i.e. /Customer/Edit/5. We have a helper that will in the background ask ClaimsAuthorizationManager (which is part of Windows Identity Foundation API) whether the current user can perform action Edit on resource Customer. If yes, HTML markup for anchor tag will be rendered. Otherwise, nothing will be rendered.
With these helpers, we've been able to have dynamic website based on background policies that define URL's user can access based on specific claims.
Now we need to push the same logic to AngularJS based SPA.
So again, goal is to skip rendering of URL-related HTML if user is not allowed to access that particular URL.
I've not been able to find any good resources on how to perform this kind of authorization with AngularJS.
Is there a proper way to do this or should I go with some custom logic?
Are there any good references that I can read on?
Angular works great in RESTful applications. In your case, you could set up your app to fetch your claims as JSON and set your angular template to render accordingly.
But you can also use MVC's helper methods on partial views and use those partials as templates for your angular application. So when your angular app fetches the html template at foo/bar/baz (via route or ng-include or directive template or whatever), your html template will come back with the MVC partial view instead of a static html file. It's a little dirty, but it works in a pinch.

Angular.js and WebAPI CRUD examples

I have a asp.net mvc4 web application which for example allows me to manage members and member resources to the site.
On the member's home page there are several different sections of details about their profile. I want to use angular.js and webapi(entityframework) to allow them to edit their address details in place and save them without a page postback. I imagine the best place to start is to have a partialview which displays these address details as part of the main page view.
Are there any examples of such a setup?
You can definitely do this. First, for switching the details based on which section the user selects you have two options:
1) Create a module and setup routes. The routes will allow you to have a base HTML page with an area where you can switch partial HTML 'views' in and out based on the URL that you are clicking on in the application. The AngularJS site has a tutorial where they do something similar. Pay notice to the ng-view explanation.
2) You can create custom directives and fetch an external HTML partial page. In the directive you 'compile' the HTML partial which allows you to use any directives that are on that page (ng-click, ng-class, etc) and then render it where the div is declared in the original page. This is a bit more advanced, so look at the ng-view example first.
For sending the data back to the mvc application, all you need to do in angular is declare a resource with the url back to the mvc app where you post the data and then send it some data. Something like this:
$resource('api/updateUserData',
{userName: userNameVar, userEmail: userEmailVar},
function(data){
//callback code where you do something with the returned data if any
}
);
There is a nice github project called angular-app that has a basic CRUD setup, shows you how to layout the angular app itself, how to use tests, how best to structure the angular files, etc. This may also be a bit more than you need for this small project, but it can at least give you some ideas on how to move forward if your app grows.

asp.net mvc routing with $routeProvider

Is there any sane way to use these?
What I want to have - is a single page with a nav-menu and <ng-view> below it.
And all the routing should be angular's responsibility.
But, I'd like to keep mvc goodness as well. I like neatly organized server-side controllers and razor pages.
I can't access .cshtml directly though, so how do I access my templates?
I don't want the main page and its content to be reloaded ever. It loads once and after that, all the navigation to other pages should be loading associated templates only.
How can I achieve that?
I can't find a single thorough example how to use them together.
Angular is used for single page web applications (SPAs).
ASP.NET MVC is used for server-side pages.
In ASP.NET MVC with Angular, your Index.cshtml or whatever your main view page is will contain all your JavaScripts and load your Angular app. You shouldn't ever navigate away from that page again. Angular's router just changes the URL (using a hash) and rebuilds the DOM based on the route.
They aren't supposed to "work together" for navigation. The only way they work together is if you create a REST API (or any API I suppose) with MVC and access it through Angular ($http, $resource, etc).
Checkout this project https://github.com/kazimanzurrashid/my-walletz-angular/blob/master/source/MyWalletz/Views/Home/Index.cshtml#L11 (shameless plug i am the owner) there is a helper method called IncludeClientView which inlines all the client side templates in the view. If you want to dynamically load the templates then create a controller and pass the template name from the client, then in the controller use partial view to return the template.
please install the AngularJS SPA Template from visual studio>> extensions and updates .

Special kind of Server Side Include of Asp.net MVC

i have to create a new asp.net mvc page that integrates content provided by a cms on the server side static. my mvc page provides a masterpage with the navigation and certain links should point to pages of the cms (which is installed on the same server). it should be something like a "server side iframe".
my idea is to create a controller which loads the page of the cms using a webrequest, extracts the body part of the page and passes the extracted data to the view. the view simply outputs the passed html. i also plan to add some logic to pass post requests to the cms (for news letter subscriptions, contact forms, ...)
now my question is: is it possible to implement this solution? or is there a better way to do this on the server side?
Could you use Application Request Routing to just hand off requests to your CMS, or do you need to include the externally provided content within an existing masterpage?
If you need to use the masterpage I would stick to the solution you suggest, although I might investigate the most robust and efficient option for querying the content from the CMS and perhaps if caching would be a good option.
It is undoubtedly possible, but keeping track of users, authentication, cookies etc. seems like a really tedious job. Also, embedding css classes, hard-coded styling etc. from the CMS in your MVC site could give you a severe headache.
If the CMS isn't home-brewed it probably has an API. In that case I would much prefer to use the API to get at the data I needed and then render that data using pure MVC. This will give you a much cleaner and more stable integration with the CMS.

What is the 'page lifecycle' of an ASP.NET MVC page, compared to ASP.NET WebForms?

What is the 'page lifecycle' of an ASP.NET MVC page, compared to ASP.NET WebForms?
I'm tryin to better understand this 'simple' question in order to determine whether or not existing pages I have in a (very) simple site can be easily converted from ASP.NET WebForms.
Either a 'conversion' of the process below, or an alternative lifecycle would be what I'm looking for.
What I'm currently doing:
(yes i know that anyone capable of answering my question already knows all this -- i'm just tryin to get a comparison of the 'lifecycle' so i thought i'd start by filling in what we already all know)
Rendering the page:
I have a master page which contains my basic template
I have content pages that give me named regions from the master page into which I put content.
In an event handler for each content page I load data from the database (mostly read-only).
I bind this data to ASP.NET controls representing grids, dropdowns or repeaters. This data all 'lives' inside the HTML generated. Some of it gets into ViewState (but I wont go into that too much!)
I set properties or bind data to certain items like Image or TextBox controls on the page.
The page gets sent to the client rendered as non-reusable HTML.
I try to avoid using ViewState other than what the page needs as a minimum.
Client side (not using ASP.NET AJAX):
I may use JQuery and some nasty tricks to find controls on the page and perform operations on them.
If the user selects from a dropdown -- a postback is generated which triggers a C# event in my codebehind. This event may go to the database, but whatever it does a completely newly generated HTML page ends up getting sent back to the client.
I may use Page.Session to store key value pairs I need to reuse later
So with MVC how does this 'lifecycle' change?
I'll attempt to comment on each of the bullet points you mentioned:
Your master pages still exist in MVC and are used to provide a consistent layout to the site. not much new there.
Your content pages will become views in the MVC world. They still provide the same content areas to your master pages.
The eventhandling of webforms should not be used in MVC, instead your Controller classes and their action methods will handle loading your data into a "model" that gets passed to the view.
Although webform style databinding is possible in MVC, I find that it is not the optimal solution. Better to place your data in a model class and strongly type your view so that you have direct access to that model. Then its simply a matter of using the <%= ViewData.Model.SomeProperty %> syntax to access your data and display it in the desired locations. As for viewstate, my recommendation is to forget that it even exists.
Remember that one of the advantages of using MVC is that you have control over the HTML you send to the client. Embrace that power and try to find solutions that allow you to maintain that control. Webform controls attempt to hide the the html from you and as such make it more difficult to customize the html when you need to.
I would highly recommend JQuery or one of the other similarly powerful javascript libraries. But learn to use them to access the HTML DOM directly and avoid the id mangling issues of webform controls.
You can use jquery to hook into the dropdown selection on the client side and submit standard or ajax style requests. Those request can return new pages, redirects, html fragments or even JSON data that can be used to update the existing page.
The asp.net Session can be used as needed.

Resources