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.
Related
I'm creating a single page app using AngularJS. I have created a main page with a custom directive for loading a form URL. I want to change the the forms based on a variable in my controller. However, I lost my bindings once I compiled and linked the form from URL
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<div ng-app="tradesman" ng-controller="application" class="form-horizontal" role="form">
Hello {{applicant.name}}
<my-form name="formName">
</my-form>
</div>
var tradesman = angular.module("tradesman")
tradesman.controller("application",function application($scope){
$scope.formName="personals";
$scope.applicant={};
});
tradesman.directive("myForm",function($http,$compile){
return {
restrict:"E",
scope:false,
replace:true,
link:function(scope,element,attrs){
var url="http://tradesman.local/views/"+scope.formName+".html";
$http.get(url).then(function(response){
scope.$watch(function(){
element.html(response.data);
$compile(element.contents())(scope);
});
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
This has successfully loaded my personals page but lost the binding in that page. More over I want a new form to be loaded whenever I change my formName in controller.
What needs to be done to make form loading and binding work simultaneously
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.
In my case, I need use #Html.ActionLink to Route to different View with AngularJS.In each view1/index.cshtml in asp.net has <div ng-view></div> that will load its html template.
the following link image is my project structure:
click
My problem is: it only route success first time.I think it cause wrong location url.
Views/Share/_Layout.cshtml:
<ul>
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("Device Management", "Index", "DeviceManagement")</li>
</ul>
Views/Home/index.cshtml:
#{
ViewBag.Title = "Home Page";
ViewBag.InitModule = "homeIndex";
}
#section Scripts {
<script src="~/app/home/homeIndex.js"></script>
}
<div ng-view><div>
app/home/homeIndex.js
var homeIndex = angular.module('homeIndex', ["ngRoute"]);
homeIndex.config(["$routeProvider", function($routeProvider){
$routeProvider
.when("/home",{
templateUrl:"app/home/homeIndex.html",
controller:"homeCtrl"
})
.otherwise({
redirectTo:"/home"
});
}]);
app/home/homeIndex.html
HOME2
app/deviceManagement/deviceManageIndex.js
var deviceManageIndex = angular.module('deviceManageIndex', ["ngRoute"]);
deviceManageIndex.config(["$routeProvider", function($routeProvider) {
$routeProvider
.when("/device", {
templateUrl: "app/deviceManagement/deviceManagementIndex.html",
controller: "deviceManageCtrl"
})
.otherwise({
redirectTo:"/device"
});
}]);
the web site has sidebar, Home and Device Management Buttons in the sidebar.
when I click Home, it will redirect right location, it can load homeIndex.html successful:
location is:
http://localhost:13060/#/home
but when I click Home Button second time, it can't load homeIndex.html anymore.
location will change to:
http://localhost:13060/#
the same problem is happened in another Button Device Management
when I click Device Management, it will redirect right location, it can load deviceManagementIndex.html successful:
location is:
http://localhost:13060/DeviceManagement#/device
but when I click Device Management Button second time, it can't load deviceManagementIndex.html anymore.
location will change to:
http://localhost:13060/DeviceManagement#
I think the location is quite strange,in first time,it should be :
http://localhost:13060/DeviceManagement/#/device
I guess that is main reason not to load html template correctly...
But why the location url can't show correctly, Please Help me solve the headache problem....
Thanks to Shawn tip!In my case, I should use angular routing in client side, $routeProvider with templateUrl to trigger servier side controller to load server side View,That's I found solution, in this way actionlink behavior could through server side, it will follow server side route rule to chose appropriate View. It shoud be work...:D
I feel ridiculous asking this question but here goes, I am trying to make a very simple ASP.NET MVC 5 app. My first of it's kind. I want to have a button that when clicked does something but doesn't change the user's view or at most returns a "Email has been submitted" message.
My problem is I can't figure out how to wire a button to an "event" or "action" that doesn't change the view(i.e. using #Html.ActionLink()) or is a Submit button. Every example I find is also of a Submit button.
Thanks for any help.
EDIT
This is still not working for me. I'll post my code below. My effort is based on what was said here and on the linked post. Also, FYI, I can make it work with `#Html.ActionLink("link text", "actionname") but that appears as a link and I am trying to use a "Button".
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<div class="hero-unit">
<h3>Marketing & Communications Project Request Form</h3>
<p>User: <strong>#Context.User.Identity.Name</strong></p>
</div>
<div class="row">
<div class="span4">
#Html.ActionLink("Send Email", "SendEmail") #*this line works*#
<input id="SendEmail" class="btn" type="button" value="SendEmail" /> #*this line does not
</div>
</div>
<script type="text\javascript">
$(function(){
var url = '#Url.Action("SendEmail", "HomeController")';
$("input#SendEmail").on('click', function() {
$.ajax({
url: url
})
});
});
</script>
HomeController
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
public ActionResult SendEmail()
{
//Code to create and send email here
return View("Index");
}
}
OK, say you have the following button, written in HTML:
<input type="button" id="MyButton" value="Click Me />
You can use jQuery to hook up to the click event:
$(function(){
$("input#MyButton").on('click', function(){
// Do what you want.
});
});
If you use a HTML helper, such as HTML.TextBoxFor(), as long as you know the id of the input that is generated, you can use the same jQuery code to hook up the click event.
EDIT:
You can place that jQuery code either in the view e.g.
<script type="text/javascript">
$(function(){
$("input#MyButton").on('click', function(){
// Do what you want.
});
});
</script>
Usually you find script code placed near the bottom of the view, but you can place it anywhere you like really.
Or you could place that jQuery in a separate JavaScript (*.js) file. Just make sure you add the following to the <head> section in _Layout.cshtml:
<script type='text/javascript' src='#Url.Content("~Scripts/YourFile.js")' ></script>
_Layout.cshtml is a master layout file that is used across your project (assuming you have picked one of the usual ASP.NET MVC project templates in Visual Studio).
EDIT:
Regards the jQuery reference, in _Layout.cshtml you can add this, if jQuery is not already referenced:
<script type='text/javascript' src='#Url.Content("~Scripts/jquery.version.js")' ></script>
Just replace the filename for the correct one you have. Now, things get interesting if your MVC app uses bundling. That's a bit out of my knowledge bank, so might be better to look at other SO questions that talk about CSS/JavaScript bundling in MVC apps.
You could simply achieve with this below sample code using jQuery ajax(post) call
<a id="btn-send-mail">SendEmail</a>
JS
$(document).ready(function(){
$('#btn-send-mail').click(function(e){
e.preventDefault();
var emailData={};
emailData.toMail='sample#testmail.com';
$.post('/Mail/Send/',{data:emailData}, function(result){
if(result.status==true){
alert('Email submitted successfully');
}});//end of post
});//end of click
});//end of ready
Controller code
public class MailController
{
[HttpPost]
public JsonResult Send(Email obj)
{
//Code for sending email
return Json(new {status=true});
}
}
If you don't want to use normal jquery call you can take advantage of Razor #Ajax.ActionLink.
You just set up the link like a normal Html.ActionLink and then create a controller action that sends your email, since this call is asynchronous it wont refresh the page.
#Ajax.ActionLink("Send Email", // <-- Text to display
"SendEmail", // <-- Action Method Name
new AjaxOptions
{
UpdateTargetId="", // <-- Used if you want to update up, DOM element ID to update
HttpMethod = "GET" // <-- HTTP method
})
I would recomend doing the jquery way but here is an example using Ajax.ActionLink
Intro
I'm developing a project with MVC.Net. I have just started a default website with a Home Controller and an Index action. I browse to the view with 'Home/Index/1' and everyting works fine.
Now I want to add an extra url parameter, so I've changed my global.asax and added a foo parameter:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}/{foo}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional, foo = UrlParameter.Optional} // Parameter defaults
);
On the page I also have a little bit of jquery. For example this script:
<script type="text/javascript">
$(document).ready(
function ()
{
});
</script>
Problem
But now when I browse to my page with 'Home/Index/1/1' I get a javascript error:
Microsoft JScript runtime error: Object expected
When I browse to the page with 'Home/Index/1' everything works fine. Probably there's a problem with my url routing, but I have no clue what I'm doing wrong.
You can also use the following syntax to force the resolution of the path
<script src="<%: Url.Content("~/Scripts/jquery-1.4.1.js") %>" type="text/javascript">
The cause of the problem is your Script source location. I assume your script source is ../../Scripts/jquery.js which this is always being created by the application when you attach a js file in your page.
Explained.
js file mapped in `../../Scripts/jquery.js`
Page is `Home/Index/1/1`
js real content is placed in `/Scripts`
when the parser looks for the js it looks in `/Home/Scripts`
which is not where it where it is. Since ../.. = /Home in Home/Index/1/1
My Suggestion is
<%
string baseUrl = "http://" + Request.Url.Host + (Request.Url.Port != 80 ? ":" + Request.Url.Port.ToString() : "");
$>
<script type="text/javascript" language="javascript" src="<%=baseUrl %>/Scripts/jquery-1.4.1.js"></script>
This also goes to your CSS files included in your page. But for CSS links you don't put " in your href attribute of the <link> tag
Related to my answer in here