Routing with AngularJS and MVC - angularjs

I have been searching the web for solutions but cant't find any that will solve my problem.
I am trying to do client side routing with AngularJS and MVC.
This is the Plunker that I am using for guide lines but it does not help me. My MVS2 Project folder structure is as follows:
$root/Views/Home/Home.html
The error I get that the page could not be found. What am I missing here?
AngularJS
// create the module and name it myApp
var myApp= angular.module('myApp', ['ngRoute']);
// configure our routes
myApp.config(function ($routeProvider) {
$routeProvider.when('/', {templateUrl: 'Home.html',controller: 'mainController'})
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function ($scope) {
// create a message to display in our view
$scope.message = 'Home Page should appear here';
});
HTML
<html data-ng-app="myApp">
<head runat="server">
<title>
<asp:ContentPlaceHolder ID="TitleContent" runat="server" />
</title>
</head
<body data-ng-controller="mainController">
<div id="Div1">
<div data-ng-view></div>
</div>
</body>
</html>

MVC blocks the Views folder from being accessed! It will always return HTTP status 404!
Why? This is done for security. It prevents visitor from looking at your view files (ascx, cshtml, vbhtml, etc) which is source code.
How it's done? You will notice that Viewsfolder has a web.config. Web.config is configured to return 404.
Here is a snippet of the web.config
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
Notice that for any path and any HTTP method, the handler is HttpNotFoundHandler
Solution: don't use the View folder for your AngularJS templates or modify web.config at your own risk

The answer that LostInComputers gave me I have found a solution to inject html pages to my MVC project.
.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/templates/Home.html',
controller: 'mainController'
})
.when('/about', {
templateUrl: '/templates/About.html',
controller: 'mainController'
})
$routeProvider.otherwise({ redirectTo: '/' });
});
What I did was to create a template folder in my root directory and added my .html pages in there.
This works perfectly for me.

Related

Unable to load controller within $routeProvider in AngularJS

This is my very first AngularJs app and created it after going through many examples on the web but I am doing something wrong here. It is highly likely because files are stored in dedicated folders. The HomeView.html template gets loaded fine but the controller doesn't. I mean I cannot get greetingMessage printed in the template. All I see is {{ greetingMessage }} instead of "Welcome!". What am I missing?
Error
Error: [$controller:ctrlreg] http://errors.angularjs.org/1.6.4/$controller/ctrlreg?p0=HomeController
App Structure
app
conponents
home
HomeView.html
HomeController.js
...
...
index.js
index.html
index.html
<body ng-app="myApp">
<h3>AngularJS</h3>
<hr />
<p>Home</p>
<div ng-view></div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.min.js"></script>
<script src="index.js"></script>
</body>
index.js
var module = angular.module('myApp', ['ngRoute']);
module.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'components/home/HomeView.html',
controller: 'HomeController'
// I tried -> controller: 'components/home/HomeController'
})
.otherwise({
redirectTo: '/'
});
});
HomeView.html
<div ng-controller="HomeController">
<h4>Home</h4>
<p>{{ greetingMessage }}</p>
</div>
HomeController.js
var module = angular.module('myApp', []);
module.controller('HomeController', [
'$scope',
function(
$scope
) {
$scope.greetingMessage = 'Welcome!';
}]);
The main reason is you haven't referred homeController.js on index.html, it should place right after index.js. This will not solve your issue. The other thing I'd like to mention is, you shouldn't be creating myApp module again while registering your controller with your myApp module. By declaring new module will flush out former registered component. So just use module getter like angular.module('myApp') and append further components to it.
<script src="components/home/HomeController.js">
Code
angular.module('myApp')
.controller('HomeController', [ '$scope',
function($scope) {
$scope.greetingMessage = 'Welcome!';
}
]);
You must be attach app file and next attache your controller file in your hoem page or master page.
This example helped you
Angular js routing

MVC and AngularJS routing

I have created an MVC application and added an Angularjs nuget.
It was created HomeController and view for it.
Home controlled isn't changed at all.
My folder hierarchy:
Index.cshtml:
<!DOCTYPE html>
<html>
<head>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>
<script src="~/Scripts/App/App.js"></script>
<title>Title</title>
</head>
<body ng-app="sampleApp">
Route 1<br />
Route 2<br />
<div ng-view></div>
<script>
var module = angular.module("sampleApp", ['ngRoute']);
module.config(
function ($routeProvider, $locationProvider) {
$routeProvider.
when('/route1', {
templateUrl: 'Views/Home.html',
controller: 'RouteController'
}).
when('/route2', {
templateUrl: 'Views/Home.html',
controller: 'RouteController'
}).
otherwise({
redirectTo: '/'
});
});
module.controller("RouteController", function ($scope) {
alert("I am here");
})
</script>
</body>
</html>
Clicking on the links produces an 404 error
http://localhost:50265/Home/Views/Home.html - this is link that was generated.
I don't understand why there is Home inserted in link.
And as the page of error said that it expected physical path
E:\SoftServe\IndividualTask\IndividualTask\Home\Views\Home.html
but i don't have Home folder in root folder E:\SoftServe\IndividualTask\IndividualTask
I set the route to 'Views/Home.html' but not to 'Home/Views/Home.html'.
What is the base path for routing? How to make it work?
MVC doesn't allow to access files from view folder..you need to
manipulate that thing by defining handler in web.config
Thank you. I have found this article: http://forums.asp.net/t/1689087.aspx?ASP+NET+MVC+Using+content+in+Views+folder and replace
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
on
<add name="BlockViewHandler" path="*.cshtml" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
in web.config file that allows to get files from the View folder and doesn't allow only *.cshtml files from it.

using ng-route in angular to route to different htmls using the routeconfig param

i new to angular routing. I have an index.html and home.html. what i am trying to do is by default the index.html should be loaded.There is a link from index.html to home.html. How would i load the index file with a default url using route like
http://localhost/myapp?user=123.
I have deployed my codebase in IIS with virtual directory as myapp.
Also when i click on the home link the url should change to
http://localhost/myapp/index.html#/home
What i am trying to do is:
app.js
var app = angular.module('myApp', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {templateUrl:'index.html', controller: 'MainController'});
$routeProvider.when('/home', {templateUrl:'home.html',controller: 'TestController'});
$routeProvider.otherwise({redirectTo: '/home'});
}]);
index.html
<div class="main" ng-controller="MainController as main">
<li>Home</li>
</div>
Controller.js
app.controller('TestController', ['$scope', '$log','$location', function($scope,$log,$location) {
$log.info("Test Controller loaded");
test();
$scope.test = function(){
console.log("Test");
}
$log.info("Test Controller function");
}])
Both the controllers are not getting loaded. The main controller is similar to test controller. What am i missing here?
I can't comment as I don't have enough reputation, but do you have the ng-app directive somewhere in your code ? Like ng-app="myApp" in a body/html tag or something like that ? Plus, if you're using angular routes, you shouldn't need the ng-controller directive in your index.html file as your controller will be set by your routeProvider.
Edit : I think it's a problem with your tags or the structure of your code.
You might have an index.html with the ng-app directive AND an ng-view
Your index.html content should be in another html file (like my nav.html in the plunker below)
That's the only thing I had to do in order to get your code working.
You can look at this plunker, which reuses mostly your code :
http://plnkr.co/edit/DbgJKe51c7QoGCG6rXlN?p=info

Route to new base page

In angular I have defined my routes like this:
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/', {templateUrl: 'pages/main.html', controller: 'MainController'});
$routeProvider.when('/login', {templateUrl: 'pages/login.html', controller: 'AccountController'});
$routeProvider.otherwise({redirectTo: '/'});
}]);
So my web site loads the pages/main.html page inside my index.html. When I goto #/login then my pages/login.html inside index.html.
But I actually don't want to load page/login.html inside index.html. I want my login page to have its own layout.
So is there a way to load login.html in such a way so that it's not included inside index.html as a partial, but so that it can have it's own base layout?
Yes you could create new html page for login page so it could use bage template
for eg:
base-template.html
<html>
<head>Your scripts</head>
<body ng-app="yourmodule">
<ng-view></ng-view>
</body>
</html>
create login.html
<div>
First Name:<input type="text"/>
Last Name:<input type="password"/>
</div>
var app = angular.module("Your module",[ngroute]);
app.config(function($routeProvider){
$routeProvider
.when('/',{
templateUrl:'login.html',
controller:'your controller'
});
app.controller("Your controller",function($scope){
//your logic
});
Hope it helps you

Route provider cannot access controllers definitions

I am trying to learn the route features of angularJS, but what I have happened so far doesn't work.
If I ever click Load, Display, or Play (in my example: the links to possible action urls)
then <div ng-view></div> still exist in the DOM (when I inspect it) , moreover it is not replaced by the related html partial file as indicated in the templateUrl of the route provider.
The Chromium log console displays an error:
Uncaught ReferenceError: LoadCtrl is not defined from my_app
If I put all the when in comments while defining the route provider, then the error is no longer thrown.
So I have thought it could depend upon the order of definition of the controllers regarding the definition of the route provider. So I have tried putting them before, or after, also in a seperate controllers.js file... But that doesn't change anything.
I suppose I am making a obvious mistake, but I cannot catch it. Any idea ?
content of index.html:
<!DOCTYPE html>
<html ng-app="my_app">
<body>
<section class="section_command">
<ul>
<li>Load file</li>
<li>Display file</li>
<li>Play file</li>
</ul>
</section>
<section class="section_content">
<div ng-view></div>
</section>
<script type="text/javascript" src="js/angular.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
content of app.js:
var app = angular.module('my_app',[]);
app.controller('LoadCtrl', function($scope, $http, $routeParams){});
app.controller('DisplayCtrl', function($scope, $http, $routeParams){});
app.controller('PlayCtrl', function($scope, $http, $routeParams){});
app.config(['$routeProvider', function($routeProvider)
{
$routeProvider.
when('/load', {templateUrl: 'partials/load.html', controller: LoadCtrl}).
when('/display', {templateUrl: 'partials/display.html', controller: DisplayCtrl}).
when('/play', {templateUrl: 'partials/play.html', controller: PlayCtrl}).
otherwise({redirectTo: '/'});
}]);
the partial html files are as simple as can be:
load.html : <span>Loading</span>
display.html : <span>Displaying</span>
play.html : <span>Playing</span>
I'm pretty sure you need to address your controllers by their string name:
when('/load', {templateUrl: 'partials/load.html', controller: 'LoadCtrl'}).

Resources