AngularJS - direct access to url with hash - url

I'm developing a webapp using AngularJS and Laravel.
When I navigate through URL and links in the app everything works fine, but if I type an URL directly in the browser, something strange happens.
For example, If I type http://myapp.dev/#/customers I get redirected to http://myapp.dev/customers#/
Why? What's wrong? Laravel executes "/" route (right) and Angular "/" route (right, again).
Note: I have made a test application similar to the first but without using Laravel and .htaccess (it serves only static HTML) and I haven't this issue, I can access URL directly.
Thank you.
Edit - here the Angular routing code:
var App = angular.module('Factotum', ['ngResource']);
function appRouteConfig($routeProvider) {
$routeProvider.
when('/', {
controller: IndiceController,
templateUrl: 'v/indice'
}).
when('/login', {
controller: 'AppController',
templateUrl: 'v/login'
}).
when('/logout', {
controller: 'AppController',
templateUrl: 'v/login'
}).
// ---- Clienti
when('/clienti', {
controller: ClientiController,
templateUrl: 'v/clienti/lista'
}).
when('/clienti/nuovo', {
controller: ClientiController,
templateUrl: 'v/clienti/nuovo'
}).
when('/clienti/modifica/:id', {
controller: ClientiController,
templateUrl: 'v/clienti/modifica'
}).
// ---- Progetti
when('/progetti', {
controller: ProgettiController,
templateUrl: 'v/progetti/lista'
}).
when('/progetti/nuovo', {
controller: ProgettiController,
templateUrl: 'v/progetti/nuovo'
}).
otherwise({
redirectTo: '/'
});
} // factotumRouteConfig
App.config(appRouteConfig);

Finally I found the problem. I'm using a free HTML5 template (Charisma by Usman - here a demo: http://usman.it/themes/charisma/), which includes jQuery History plugin. I removed this plugin, along with some initialization code, and now all is working as expected.
My fault, I didn't inspect the code carefully.

Related

ASP.NET MVC with angular routing url issue

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.

how to use angular routing to nest 3 mvc razor models

I want to have a UsersAdmin view that has Account Registration, UserProfile class and a Identity Role class. I am using MVC5 with default Individual Authentication.
I am using ui-router for my routing. I have seen many examples using a viewmodel to pass multiple models to a single cshtml view. But I am needing a more complex setup. I created a mock up of what I am looking for. What is the best way to do this.
Here is what my setup looks like
ui-routing
// Default route
$urlRouterProvider.otherwise('/Document');
// Application Routes States
$stateProvider
.state('app', {
abstract: true,
controller: "CoreController",
resolve: {
_assets: Route.require('icons', 'toaster', 'animate')
}
})
.state('app.document', {
url: '/Document',
templateUrl: Route.base('Document/Index'),
resolve: {}
})
.state('app.register', {
url: '/Register',
templateUrl: Route.base('Account/Register'),
resolve: {}
}).state('app.applicationUser', {
url: '/ApplicationUser',
templateUrl: Route.base('ApplicationUsers/Index'),
resolve: {}
}).state('app.role', {
url: '/Role',
templateUrl: Route.base('Role/Index'),
resolve: {}
}).state('app.roleCreate', {
url: '/RoleCreate',
templateUrl: Route.base('Role/Create'),
resolve: {}
}).state('app.userProfile', {
url: '/UserProfile',
templateUrl: Route.base('UserProfiles/Index'),
resolve: {}
}).state('app.userProfileCreate', {
url: '/UserProfileCreate',
templateUrl: Route.base('UserProfiles/Create'),
resolve: {}
}).state('app.login', {
url: '/Login',
templateUrl: Route.base('Account/Login'),
resolve: {}
});
}
_Layout.cshtml
<div ui-view class="app-container" ng-controller="CoreController">#RenderBody()</div>
Navigation
<li>
<a ui-sref="app.userProfile" title="Layouts" ripple="">
<em class="sidebar-item-icon icon-pie-graph"></em>
<span>User Profile</span>
</a>
</li>
I have no issue using modals for the Create,Details,Edit views if that is a easier solution. However I do not know how to pass the selected Id with its properties to the modal.
I believe that I answered your question to someone else. You want to gather information through the URL, right?
Using routes in AngularJS to gather data
ui-router can help you achieve this by using
a.
ui-sref='stateName({param: value, param: value})'
The parameterr object passed along with the state name can be accessed in the controller using $stateParams
b.
In your controller you could do something like
if ($stateParams.id != null) {
// service call goes here
}
c. You need to use named views
Something like
$stateProvider
.state('report', {
views: {
'filters': { ... templates and/or controllers ... },
'tabledata': {},
'graph': {},
}
})
where
filters
and
tabledate
are the named views.
ui-view has a decent example for it here https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Btw , I would suggest you first figure out the panels which are dynamic ( i.e the ones whose content changes because of some kind of user interaction ) vs static ones ( they dont change once loaded) . You should only be looking at ui-views to replace the dynamic parts , there is no point in making the app more complicated by putting everything in a child view . The states can become very confusing very quickly.
I use the ng-include directive to load the static views in the parent state and only define child states for portion of the views that change.
<div ng-include="'/MyStaticView'" ng-show="MyCondition == true "></div>

AngularJs routing with Asp.Net Mvc

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.

#routeprovider angularjs and MVC

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

Angular app on IIS 8.x virtual directory has strange URL behavior

I'm having a problem with Angular JS on IIS 8.x with MVC. My application index page with virtual directory is like so:
https://myapp.xyz/VirtualDirectory/
That page loads the angular app. My angular routes are set up as:
$routeProvider
.when('/', {
templateUrl: 'Content/Partials/Home/Index.html'
})
.when('/Error', {
templateUrl: 'Content/Partials/Shared/Error.html'
})
.otherwise({
redirectTo: '/Error'
});
So, if I access the first link, my URL looks like:
https://myapp.xyz/VirtualDirectory/#/
This works perfectly and resolves my partials fine. Angular requests the partials with the virtual directory in it so I see an HTTP request to:
https://myapp.xyz/VirtualDirectory/Content/Partials/Home/Index.html
However, if I access without a trailing slash like:
https://myapp.xyz/VirtualDirectory
Angular routes to:
https://myapp.xyz/VirtualDirectory#/
Once this happens, none of my routes work (they do not respect the virtual directory). They route as:
https://myapp.xyz/Content/Partials/Home/Index.html
This breaks all of my routes and templates defined in my directives. Any suggestions on how to fix this issue?
try to add this in you head tag.
<html>
<head>
<base href="/VirtualDirectory/">
</head>
<body>
...
</body>
I found that if you use the ./ syntax for the path, you don't need to involve Razor.
Code which fails:
$routeProvider.when("/productList", {
templateUrl: "/app/products/productListView.html", controller: "ProductListController as vm"
});
Code that works: (note the . before /app)
$routeProvider.when("/productList", {
templateUrl: "./app/products/productListView.html", controller: "ProductListController as vm"
});

Resources