I'm trying to build a SPA with Asp.Net MVC. for this I'm using angularJs routing .
This is my project hierarchy.
My Layout.cshtl code
<html lang="en" ng-app="ProjectTrackingModule">
<head>
<script src="~/Scripts/jquery-2.1.0.min.js"></script>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
<script src="~/Scripts/app.js"></script>
</head>
<body>
Home
Projects
<div ng‐view style="margin‐left: 10%; margin‐right: 10%;">
</div>
//... footer
</body>
</html>
My app.Js code is as follow:
var app = angular.module('ProjectTrackingModule', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
$routeProvider
.when("/Home", {
templateUrl: "/Views/Home/Home.cshtml",
controller:"HomeController"
})
.when("/Projects", {
templateUrl: "/Views/ProjectManagement/ProjectDetails.cshtml",
controller: "ProjectsController"
})
.otherwise({redirectTo:"/Home"})
});
I want to load my Home.Cshtml partial view inside ng-view. But when I run my application, It only showing Home partial view.
also when I click on Project, then it should render ProjectDetails.cshtml inside ng-view.
code inside ProjectDetails.cshtml
<div ng-controller="ProjectsController">
<h2>ProjectDetails</h2>
</div>
I think you have some misonceptions about Angularjs routing concepts.
MVC Routing :
ASP.NET routing enables you to use URLs that do not have to map to specific files in a Web site. Because the URL does not have to map to a file, you can use URLs that are descriptive of the user's action and therefore are more easily understood by users.
Angular Routing :
Angular.js routing using MVC framework does not use MVC routing.
Comparable parts are:
Model ===== ng-module
controller ===== ng-controller
view ===== ng-view
So you can't call the MVC Controller in your angularjs route config. Does this make sense?
Also please think about some of the differences between cshtml and html.
Angular routing and MVC routing are totally different because:
Angular routing is use client side
MVC routing is used server side
The above texts are for your understanding only.
I think this discussion will help you :
How to use ASP.NET MVC and AngularJS routing?
Update :
The href is wrong in Anchor tag.
Its should be href="#/Home", not href="#Home"
So please change your code
Home
Projects
Lets understand the routing in angular first. lets say your url says
www.example.com/Home/Index -- this points to your MVC HomeController and Index ActionMethod. Now what mvc does, it returns you the first View only.
say you have an anchor Load the New View. Clicking this will result in a new Url www.example.com/Home/Index#/angular-route. This url will still hit the same MVC HomeController and ActionMethod.
But you have an additional route in angular
`var app = angular.module('ProjectTrackingModule', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
$routeProvider
.when("/angular-route", {
templateUrl: "/Html/GetHtml?type=angular-route",
controller:"AngularController"
})
.otherwise({redirectTo:"/Home"})
});`
Here in the code section templateUrl: "/Html/GetHtml?type=angular-route",
Html is MVC Controller and GetHtml is ActionMethod. This ActionMethod returns you the new view that you want according to the angular route, that's why we are sending a parameter type too to help us decide.
controller:"AngularController" says that angular will call its controller after the page is returned from you mvc controller. It's Angular's Controller and it has nothing to do with your MVC controller.
you declare angular controller like this:
app.controller('AngularController',function($scope){
alert("my js controller is called");
});
Hope this helps you to find a solution.
Have a simple example can apply to your project. Example our MVC application has four pages as Home, Contact, About and User, we want to create a angularjs template for each pages, so how we do routing for it? how to make angularjs controller for it?
Basic code as following:
Routing:
$routeProvider
.when('/', { // For Home Page
templateUrl: '/AngularTemplates/Home.html',
controller: 'HomeController'
})
.when('/Home/Contact', { // For Contact page
templateUrl: '/AngularTemplates/Contact.html',
controller: 'ContactController'
})
.when('/Home/About', { // For About page
templateUrl: '/AngularTemplates/About.html',
controller: 'AboutController'
})
.when('/Home/User/:userid', { // For User page with userid parameter
templateUrl: '/AngularTemplates/User.html',
controller: 'UserController'
})
.otherwise({ // This is when any route not matched => error
controller: 'ErrorController'
})
}]);
Controller:
var app = angular.module('MyApp'); app.controller('UserController', ['$scope', '$routeParams', function ($scope, $routeParams) {
$scope.Message = "This is User Page with query string id value = " + $routeParams.userid;}]); ...
Full article with download code for it at Angularjs routing asp.net mvc example
You cannot directly point on the .cshtml file but you can point to a templateUrl that points to an MVC route.
Considering you are using the default MVC route {controller}/{action}/{id?}, for example:
var app = angular.module('ProjectTrackingModule', ['ngRoute', 'ui.bootstrap']);
app.config(function ($routeProvider) {
$routeProvider
.when("/Home", {
templateUrl: "/Home/Home", //points to an mvc route controller=Home, action=Home
controller:"HomeController"
})
.otherwise({redirectTo:"/Home"})
});
But in order for it to work the MVC Action should be in the controller also.
public class HomeController : Controller
{
[HttpGet]
public ActionResult Home()
{
return View();
}
}
also your anchor tags points to an incorrect href, it should have the hashbang (#)
Home
Projects
Simple way to do it would be like follows:
MyAngularApp.js
var myAngularApp = angular.module('MyAngularApp', ['ngRoute']);
myAngularApp.config(function ($routeProvider) {
$routeProvider
.when("/myprojects", {
templateUrl: "MyAspMvcCtrl/GetTemplate?id=myprojects",
controller:"MyAngularController"
})
...
.otherwise({redirectTo:"/myprojects"})
});
myAngularApp.controller("MyAngularController", function ($scope) {
...
// Do something
$scope.mydata = {
id = 1234,
msg = "Hello"
};
});
ASP.Net MVC Controller
public class MyAspMvcCtrlController : Controller
{
[HttpGet]
public ActionResult GetTemplate(string id)
{
switch (id.ToLower())
{
case "myprojects":
return PartialView("~/Views/ProjectManagement/ProjectDetails.cshtml");
default:
throw new Exception("Unknown template request");
}
}
}
Layout.cshtml
<html ng-app="myAngularApp">
...
<body>
...
<div ...>
...
My Projects
...
</div>
<div ng-view></div>
...
</body>
</html>
ProjectDetails.cshtml
<div ...>
<h3>ID: {{mydata.id}}</h3>
<p>Message: {{mydata.msg}}</p>
</div>
AngularJs Routing Does not working with cshtml files !!
if you want to use angularjs routing with mvc view (cshtml) file use both routing:
angular routing + mvc routing
your routing code should be like this:
.when("/Home", {
templateUrl: "/Home/Home",
controller:"HomeController"
});
where First Home is Controller Name
and Second Home is The Action Name at the Mvc Controller.
Related
I have problem with angular routing and ASP.NET MVC.
The problem is with URL.
MVC controller:
[RoutePrefix("BackOffice/Merchants")]
public class MerchantsController : Controller
{
[Route("Add")]
public ActionResult Add()
=> View("~/Views/BackOffice/Merchants/View.cshtml");
[Route("{id}/Edit")]
public ActionResult Edit(Guid id) // e08c5580-29e3-4429-9c76-b1464f0365ae
=> View("~/Views/BackOffice/Merchants/View.cshtml");
}
Angular app.js
var app = angular.module("backofficeMerchantsApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/",
{
template: "<h1>eee</h1>"
})
.when("/Add",
{
templateUrl: "add.html",
controller: "addController"
});
});
And there is problem:
When I enter:
.../BackOffice/Merchants/Add
The angular loads "/" page.
When I enter:
.../BackOffice/Merchants/Add#/Add
The angular loads "/Add" page.
I don't want it. What I have done wrong?
I want to:
When I enter:
.../BackOffice/Merchants
The angular loads "/" page.
When I enter:
.../BackOffice/Merchants/Add
The angular loads "/Add" page.
How to do it?
I was able to figure this out here: Angular Routing with ASP MVC
Hope this helps if you are still having a hard time.
I am trying to understand the AngularJS routing when it is used with ASP.net MVC. I am following this article to understand AngularJS routing. My query is specific to the usage of 'templateURL'. I understand that in pure AngularJS routing, templateUrl points to a specific '.html' page. But in the many example applications that I have seen in the internet for AngularJS and ASP.net MVC, I have seen that templateURL does not point to a specific .html, but a path of the view folder is given, not the .html file (or .cshtml file, which i know can be processed only by ASP.net MVC framework). For example from the article, following is the routing information given in the AngularJS javascript:
NbCapp.config(function ($routeProvider) {
$routeProvider
.when('/ondemand', {
controller: 'onDemandController',
templateUrl: 'ondemand/ondemand'
})
.when('/results', {
controller: 'resultsController',
templateUrl: 'results/results'
})
.otherwise({ redirectTo: '/results' });
});
As observed from the above, all the routing, points to a folder not a .html file. Could anyone please help me understand how this works.
I understand that in pure AngularJS routing, templateUrl points to a specific '.html' page.
Not necessarily. It doesn't matter what extension is or whether there is extension at all or not. The only thing that matters is Content-Type of the document fetched as template. So as long as it's text/html - it can be used as template. (Actually GET request for template will be issued and response processed as template (will be displayed on the page), so it doesn't even matter what server responds with Angular will just take responseText of the response data, but better if it is text/html).
In your example, templateUrl: 'results/results' might point to some dynamic framework resolved user-friendly path without any extensions, which responds with HTML content.
AngularJS does not necessarily have to point to an HTML page. What you have specified above is a combination of controller/action. When you call an action you get a processed CSHTML, VBHTML, or ASPX as an HTML response.
For example, specifying:
templateUrl: 'Account/LogOn'
will instantiate an AccountController and call LogOn action that will return PartialViewResult.
templateUrl does not require only .html template. Basically ui-route loads the content from given template url and accept that Content-Type : 'text/html'. Template loadin g is done by ajax.
So you are free to load any template with any extension but with valid path.
In Asp.net MVC we define custom routing in RouteConfig File. Suppose in RouteConfig we have declared custom route as follows:
routes.MapRoute("AngularTemplates", "almight/{name}", new { controller = "Home", action = "Template" });
and in app.js file, we have configured angular route as follow:-
var app = angular.module("BeautyParlorAppModule", ["ngRoute"]);
app.config(function ($routeProvider) {
debugger
$routeProvider
.when("/DetailView",
{
templateUrl: "almight/detailsView",
controller: "DetailviewController"
}
)
.when("/ListView",
{
templateUrl: "almight/_ListView",
controller: "ListViewController"
}
);
});
In HTML file we have action like:
<div class="row">
<div class="col-md-12">
<div class="nav">
<ul>
<li>Show ListView</li>
<li>Show DetailView</li>
</ul>
</div>
</div>
Upon clicking on link will locate home controller of MVC and call action Template with Name parameters _ListView or detailsView
public class HomeController : Controller
{
public ActionResult Index(string id)
{
return View();
}
public ActionResult Template(string name)
{
if (name == null || !Regex.IsMatch(name, #"^[-\w]+$"))
throw new ArgumentException("Illegal template name", name");
relativeViewPath=String.Format("~/Views/Home/{0}.cshtml",name);
return View(relativeViewPath);
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}
I m having one index page and one child page. In my index page, I m trying to render my child. but somehow things not working as expected and Angular routing not working as expected
Here is my index page
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<body ng-app="AngularApp">
<div> My message {{message1}} </div>
First child
<div></div>
<div ng-view></div>
</body>
#section scripts{
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/angular-resource.js"></script>
<script src="~/Modules/AngularApp.js"></script>
}
Here is my angularApp.Js file where I have defined the routing
var myapp = angular.module('AngularApp', ['ngRoute']);
myapp.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/',
{
templateUrl: '/Index',
controller: 'IndexController'
})
.when('/FirstChild',
{
templateUrl: '/Angular/FirstChild',
controller: 'ChildController'
});
$locationProvider.html5Mode(true).hashPrefix('!')
});
myapp.controller('IndexController', function ($scope) {
alert('My Index');
$scope.message1 = "My Index";
});
myapp.controller('ChildController', function ($scope) {
alert('My Child Index');
$scope.FirstMessage = 'My First Message';
});
Here is my ASP.NET MVC Action for rendering the partial view. My controller name in ASP.NET MVC is Angular
public ActionResult FirstChild()
{
return PartialView("Firstchild");
}
Problem 1:
When I run the application with Index as the start page, this is the URL, I m seeing in the browser, http://localhost:59367/Angular/Index but the corresponding controller in Angular side for index page is not triggered
Problem 2:
When I click the First child link in my index page, its taking me to a completely page rather than rendering the partial view inside the ng-view.
http://localhost:59367/Angular/FirstChild
I m pretty sure there is serious problem in Angular routing which I defined but couldn't figure it out:( Please help
Problem Summary:
On further analysis, its been found that, once I click the "First child", ideally the URL should read like Angular/Index#/FirstChild but what happens here is, "ASP.NET MVC Action First Child is getting called and the URL is changing completely"
Problem has been identified. The article which I followed has used the below part
$locationProvider.html5Mode(true).hashPrefix('!')
in the app.js file. I have removed it due to some issues in my local. But while doing so, I didn't update the part in my index page for this line
First child
It has to be
First child
Now angular routing started working fine without any issues. :)
Updated Question:
I tried including the line in d code and I removed as # in my the href but it was not working.. Seems like angular routing has to be updated as well.
$locationProvider.html5Mode(true).hashPrefix('!')
Can someone help me in updating it in the correct format.
I have a MVC View (Say Index) where I am loading multiple views via AngularJS and I have defined the angular route something like
angular.module("myModule", []).config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/Home/View1', { templateUrl: '/ngViews/View1.html', controller: 'Controller1' });
$routeProvider.when('/Home/View2', { templateUrl: '/ngviews/View2.html', controller: 'Controller2' });
$locationProvider.html5Mode(true); });
Now I want if there is link like /Home/Details (or Test/AnotherAction )which is not provided using $routeprovider then it should call MVC action. Please suggest the best way to handle it.
Thanks a lot in advance
I'm currently working on an ASP.NET MVC project to which some AngularJS was added - including some AngularJS directives.
I need to add to an AngularJS directive a MVC partial view. Obviously,
#Html.Partial("_PartialView", {{name}})
doesn't work.
So far all my searches online provided no help.
Any idea how I could render a partial view inside an Angular directive?
Thanks!
Angular exists strictly on the client side whereas MVC views exist on the server side. These two cannot interact directly. However, you could create an endpoint in which your partial view is returned as HTML. Angular could call this endpoint, retrieve the HTML, and then include it inside a directive.
Something like this:
app.directive("specialView", function($http) {
return {
link: function(scope, element) {
$http.get("/views/partials/special-view") // immediately call to retrieve partial
.success(function(data) {
element.html(data); // replace insides of this element with response
});
}
};
});
app.directive("myDirective", ['', function () {
return {
restrict: 'A',
scope: {
foo: '='
},
templateUrl: '/home/_myDirectivePartialView',
}]
} }]);
Just need to use templareURL and specify the route to get the partial view.