I am trying to implement angularjs routing with cshtml but i am unable to accomplish it. Can someone look into this ? what i am doing wrong.
index.cshtml:
Route 1
productmodule.js
var app = angular.module("productmodule", ["ngRoute"]);
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/route1', {
templateUrl: '/Product/Details',
controller: 'ProductController'
}).
otherwise({
redirectTo: '/'
});
}]);
Details.cshtml
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
<div ng-view=""></div>
</body>
</html>
ProductController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace webapp.Controllers
{
public class ProductController : Controller
{
//
// GET: /Product/
public ActionResult Index()
{
return View();
}
public ActionResult Details()
{
return View();
}
}
}
What i wanted to achieve is when I click the Route 1 link from ( index.cshtml) I should be able to navigate to Details.cshtml
When you click your anchor tag it's going to send a request to the server (i.e. the MVC routing) for the resource at "/". Being that you didn't specify a controller or action it will look for the default, which is Home/Index (assuming you haven't changed the default route configuration). Look for code similar to the following in your .NET project.
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index" }
);
If you want Product/Index to be the default you can change "Home" to "Product". Alternatively you can change your anchor tag to specify the controller.
Route 1
Either way, MVC will deliver the Index view and at that point Angular's routing will take over, examine the "#/route1" and load the appropriate ng-view.
Related
Ok so I am fairly new at AngularJS and just running through a demo, but I am having issues with the routing side of things and can't figure it out. I thought you guys would know instantly that I have done something dumb.
So here goes.
This is my JS file
var WebApplication2 = angular.module('WebApplication2', ['ng-route']);
WebApplication2.controller('LandingPageController', LandingPageController);
WebApplication2.config([
'$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/routeOne', {
templateUrl: 'routesDemo/one'
})
.when('/routeTwo', {
templateUrl: 'routesDemo/two'
})
.when('/routeThree', {
templateUrl: 'routesDemo/three'
});
}
]);
And here is my html code
<html ng-app="WebApplication2" ng-controller="LandingPageController">
<head>
<title ng-bind="models.helloAngular"></title>
</head>
<body>
<h1>{{models.helloAngular}}</h1>
<ul>
<li>Route One</li>
<li>Route Two</li>
<li>Route Three</li>
</ul>
<div ng-view></div>
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
#Scripts.Render("~/bundles/AngularBundle")
</body>
</html>
I also have this js controller file
var LandingPageController = function ($scope) {
$scope.models = {
helloAngular: 'I work!'
};
}
I then have a controller with the following actionresults
public class RoutesDemoController : Controller
{
public ActionResult One()
{
return View();
}
public ActionResult Two()
{
return View();
}
public ActionResult Three()
{
return View();
}
}
This is a dependency injection error.
Try this :
var WebApplication2 = angular.module('WebApplication2', ['ngRoute']);
instead of :
var WebApplication2 = angular.module('WebApplication2', ['ng-route']);
Since you are using routing, you should not declare an ng-controller attribute on your view. With routing, each of your views can use a different controller.
Instead of the HTML tag you mentioned above, it should be like this:
<html ng-app="WebApplication2">
You should declare the controller you wish to use in your route. The templateUrl is the path to the HTML file you will use as the template:
$routeProvider.when('/routeOne', {
templateUrl: 'views/route-one.html',
controller: 'LandingPageController'
})
Your controller's code should look something like this:
WebApplication2.controller('LandingPageController', function ($scope) {
$scope.models = {
helloAngular: 'I work!'
};
});
Where you are using <h1>{{models.helloAngular}}</h1> that is not in the scope of your route. The views for your routes will render in <div ng-view></div>.
In your views/route-one.html file you can add <h1>{{models.helloAngular}}</h1>.
You can view this page in the docs for an example implementation of ngRoute.
Angular is used to build single-page applications—your ASP.net's router will have nothing to do with Angular's routes. You just need to declare a single static route that is pointed to your Angular application. Server-side and client-side routing will not work hand-in-hand.
I'm routing the views using ngRoute and not having any particular issues rendering most views. The only problem I am having is when I do a post method and passing a list to the view.
Site/Page renders the view with no layout.
Typing into the address bar http://localhost:7351/Page works and provides layout but obviously no View. If I post the form in http://localhost:7351/Main the browser URL changes to http://localhost:7351/Site/Page and displays the results without any layout.
Form in view Main
<form method="post" action="Site/Page">
<input id="chk_main" type="checkbox" />
<input type=submit>
</form>
RouteConfig
routes.MapRoute(
name: "Page",
url: "Site/Page",
defaults: new { controller = "Site", action = "Page" }
);
EDIT: If I change "url: Site/Page" to "url: Page" the Layout will show, but then View won't.
Controller
public ActionResult Index()
{
return View();
}
public ActionResult Main()
{
return View(persons);
}
[HttpPost]
public ActionResult Page()
{
return View();
}
Angular Route Provider:
$routeProvider.
when('/Main', {
templateUrl: 'Site/Main'
})
.when('/contact', {
templateUrl: 'Site/Contact'
})
.when('/Page', {
templateUrl: 'Site/Page'
})
Is there something that i'm missing or don't understand.
I am developing a ASP.NET MVC 5 application. I am loading a partial view through angular 'ui.router' on a div in a parent page. Routing is working great until I refresh the page - than a partial view is loading on a whole page but I want it to still load as a partial.
This is my code. A parent view, FirstPage.cshtml:
<html ng-app="myApp">
<head>
<base href="/">
<title>First Page</title>
<script src="/Scripts/Angular/angular.js"></script>
<script src="/Scripts/Angular/angular-ui-router.js"></script>
<script src="/Scripts/app.js"></script>
</head>
<body>
<h1>First Page</h1>
<ul id="myMenu">
<li ui-sref="customer">Customer</li>
</ul>
<div ui-view="containerOne"></div>
</body>
</html>
This is my app.js:
var myApp = angular.module("myApp", ['ui.router']);
var proposalConfig = function ($stateProvider, $locationProvider) {
$locationProvider.hashPrefix('!').html5Mode(true);
$stateProvider
.state('customer', {
url: 'Proposal/Customers',
views: {
"containerOne": {
templateUrl: '/Proposal/Customers'
}
}
});
}
proposalConfig.$inject = ['$stateProvider', '$locationProvider'];
myApp.config(proposalConfig);
My RouteConfig.cs:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "ProposalCustomers",
url: "Proposal/Customers",
defaults: new { controller = "Proposal", action = "Customers" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
My ProposalController.cs:
public ActionResult Customers()
{
return View();
}
public ActionResult FirstPage()
{
return View();
}
My Views/Proposal/Customers.cshtml:
<h2>Customer list</h2>
I hope my problem is clear.
EDIT:
I changed my RouteConfig.cs following the solution from this article:
http://www.codeproject.com/Articles/806500/Getting-started-with-AngularJS-and-ASP-NET-MVC-P
to have a default route like this:
routes.MapRoute(
name: "Default",
url: "{*url}",
defaults: new { controller = "Proposal", action = "FirstPage" }
When I refresh a page that has a route exactly like my controller/action, it still loads that specific route on a whole page instead as a partial. If I change a .state url to something else page refresh is working. But still if I put manually a controller/action path in the URL, it shows a view on a whole page instead as a partial.
Is there a way to avoid this?
You need to change you ng-view to ui-view as you are using angular $stateProvider not angular $routeProvider
HTML
<body>
<h1>First Page</h1>
<ul id="myMenu">
<li ui-sref="customer">Customer</li>
</ul>
<div ui-view=""></div>
</body>
You stateProvider should be change which is currently using single view and you declared it as like you are using nested-views
Config
var myApp = angular.module("myApp", ['ui.router']);
var proposalConfig = function($stateProvider, $locationProvider, $urlRouterProvider) {
$locationProvider.hashPrefix('!').html5Mode(true);
$urlRouterProvider.otherwise('/Proposal/Customers'); //default redirection if no route matched
$stateProvider.state('customer', {
url: '/Proposal/Customers',
templateUrl: '/Proposal/Customers',
controller: 'someController' //if you want
});
}
proposalConfig.$inject = ['$stateProvider', '$locationProvider'];
myApp.config(proposalConfig);
Hope this could help you, Thanks.
Ok, so what I'm guessing is happening is you mapped a route in your MVC application to serve the same route as your angular application, in this instance, you mapped 'Proposal/Customers' in your MVC router and in your Angular-UI-Router.
So what is happening is that if you're already in your Angular application, the Angular router has control and as you navigate around, it is loading the template as a child template and putting the HTML into the correct location. When you refresh, you're sending that route to the MVC router, though, and it's serving the HTML as the page.
EDIT
Forgot to mention, this is happening because you've got html5 routing turned on.
I using MVC4 and DependencyResolver with Unity. Like in Brad Wilson's blog page http://bradwilson.typepad.com/blog/2010/07/service-location-pt3-views.html, i want to use dependency injection for my views. But it seems that MVC4 view engine does not attempt to create the view page classes via the DependencyResolver. Does it, or maybe i do something wrong?
Here is my code:
public static void Register() {
var unity = new UnityContainer();
unity.RegisterType<SpaceProject.Models.SpaceShipEntities>(new RequestLifetimeManager());
DependencyResolver.SetResolver(new UnityDependencyResolver(unity));
}
public abstract class SharedView : WebViewPage
{
[Dependency]
public SpaceProject.Models.SpaceShipEntities Context { set; get; }
}
and my _Layout.cshtml:
#inherits SharedView
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head></head>
<body>
#foreach (var menu in Context.Menu) {
<li>
#menu.Title |
</li>
}
</body>
</html>
I have error that Context is null.
#inherits SharedView not work in _Layout.cshtml, i think because it is not view and used like Master Page. In views and partial views all works perfect.
I am using ASP.NET MVC 3.0 and getting the following error in *_Shared\Layout.cshtml*
Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.
I get error at #{ Html.RenderAction("Menu", "Nav"); }
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
</head>
<body>
<div id = "header">
<div class = "title">SPORTS STORE</div>
</div>
<div id = "categories">
#{ Html.RenderAction("Menu", "Nav"); }
</div>
<div id = "content">
#RenderBody()
</div>
</body>
</html>
In Controllers\NavController:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SportsStore.Domain.Abstract;
using SportsStore.WebUI.Models;
namespace SportsStore.WebUI.Controllers
{
public class NavController : Controller
{
private IProductRepository repository;
public NavController(IProductRepository repo)
{
repository = repo;
}
public PartialViewResult Menu()
{
IEnumerable<string> categories = repository.Products
.Select(x => x.Category)
.Distinct()
.OrderBy(x => x);
return PartialView(categories);
}
}
}
In Views\Nav\Menu.cshtml:
#model IEnumerable<string>
#
{
Layout = null;
}
#Html.ActionLink("Home", "List", "Product")
#foreach (var link in Model)
{
#Html.RouteLink(link, new
{
controller = "Product",
action = "List",
category = link,
page = 1
}
)
}
I could make the example to work.
There is a problem, however, with the code as it is posted. Note the line break in your exampe:
#
{
Layout = null;
}
While it should actually be
#{
Layout = null;
}
It generates the error you quoted "Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'", which is unhelpful, but when I pressed F5 I was taken to a page with a better description:
Parser Error Description: An error occurred during the parsing of a
resource required to service this request. Please review the following
specific parse error details and modify your source file
appropriately.
Parser Error Message: A space or line break was encountered after the
"#" character. Only valid identifiers, keywords, comments, "(" and
"{" are valid at the start of a code block and they must occur
immediately following "#" with no space in between.
Use the [ChildActionOnly] attribute on the Menu action like this:
[ChildActionOnly]
public PartialViewResult Menu()
{
IEnumerable<string> categories = repository.Products
.Select(x => x.Category)
.Distinct()
.OrderBy(x => x);
return PartialView(categories);
}