Angular JS for creating a master page child page effect - angularjs

I need this Master Page and Child Page functionality in my application that uses HTML and calls Web Apis using AngularJS.
I'm having a problem in routing in this scenario.
Code used for Routing in Route.js:
var MainApp = angular.module('MainApp', ['ngRoute']);
MainApp.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '../partials/DashboardMenu.html',
controller: 'DashboardMain'
})
.when('/Holidays', {
templateUrl: '../partials/Holidays.html',
controller: 'Holidays'
})
.when('/Projects', {
templateUrl: '../partials/Projects.html',
controller: 'Projects'
})
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix('!');
});
Dashboard.html
<body ng-app="MainApp" ng-controller="DashboardMainController">
<div class="view-animate-container">
<div ng-view class="view-animate"></div>
</div>
DashboardMenu.html
<div class="container-fluid btn-group">
<div class="row">
<a href="../partials/MyProfile.html" class="thumbnail">
<img src="" alt="My Profile" />
</a>
<a href="../partials/Projects.html" class="thumbnail">
<img src="" alt="Projects List" />
</a>
<a href="../partials/Holidays.html" class="thumbnail">
<img src="" alt="Holidays List" />
</a>
</div>
Below is the folder structure in my application:
After the User logs in from the Login Page, the user should be redirected to Dashboard.html with the default child view as DashboardMenu.html
In login Service.cs, when I authenticate the User and try to redirect him to the Dashboard.html with the below code snippet, it's just appending the URL with the Dashboard.html.
$location.path('DashboardMenu.html')
For this, I've added <base href="/" /> in Dashboard.html and locationProvider.html5mode and hasprefix but nothing worked for me. Please let me know where I'm missing..

It sounds like you are trying to implement some kind of version of nested views with ngRoute, which does not support that. I would suggest using ui-router which has support for nested states.

$location.path() should be set to url value that matches in your routing config.....not to the template path
Try changing
$location.path('DashboardMenu.html')
to
$location.path('/')
Same with your href values.... should be url not template
Chnge
<a href="../partials/Projects.html" class="thumbnail">
to
<a href="/Projects" class="thumbnail">
NOTE: Make sure server is configured for using html5Mode
You also need to remove ng-controller from templates that are used by routing that have controller declared already in the routing config. Otherwise you will end up with 2 instances of the controller running
Might suggest you study some more tutorials

Related

AngularJS: Load page on link click

I got 2 divs, first has links pointing to individual pages and another one to display the content of pages the links are pointing to. Here is how it looks:
<div id="navigation">
<a href="http://mydomain/page1">
<a href="http://mydomain/page2">
<a href="http://mydomain/and-so-on">
</div>
<div id="content">
<!-- display content here -->
</div>
Is there a way to prevent redirecting the page on link click and display the content of the URL they point to? I'm doing it this way for SEO purposes so each individual pages can also be crawlable on their own.
I've heard of ng-include but I want to be sure I'm heading the right direction so I reckon I should ask first before going with it.
Thank you in advance.
Use AngularJS Routing for this purpose.
<a href="#page1">
<a href="#page2">
<a href="#and-so-on">
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("page1", {
templateUrl : "http://yourDomain/page1.html"
})
.when("/page2", {
templateUrl : "http://yourDomain/page2.html"
})
.when("/and-so-on", {
templateUrl : "http://yourDomain/and-so-on.html"
});
});
</script>
Note: Must include angular-route.js

IIS Virtual Directory with MVC6 Angular Routing 1.4.5

I have a MVC6/Angular site that will have multiple applications, but for now it just has one. When it is complete an example will be App1 and App2 being.cshtml pages with only a div with a data-ng-app and data-ng-view attribute:
mysite.come/virtualdir/App/App1:
<div class="row" data-ng-app="app-app1">
<div data-ng-view></div>
</div>
mysite.come/virtualdir/App/App2
<div class="row" data-ng-app="app-app2">
<div data-ng-view></div>
</div>
For angular, I understand if I have a virtual directory in IIS i need to include in my the header section of the _Layout.cshtml (Actually putting this in the _Layout will break development):
<base href="#Url.Content("~/")" />
My original templateUrl and angular links for app1 in development are:
$routeProvider.when("/", {
templateUrl: "/views/app1/index.html"
});
$routeProvider.when("/items", {
controller: "receiveController",
controllerAs: "vm",
templateUrl: "/views/app1/receiveView.html"
});
// typical link in html page for app1
<a data-ng-href="#/items"></a>
When I deploy to IIS i need to have the routing below to get to my index page to load when the the user navigates to mysite.come/virtualdir/App/App1
$routeProvider.when("/", {
templateUrl: "../views/app1/index.html"
});
After that none of my other links work:
<a data-ng-href="#/items"></a> navigates me to mysite.com/virtualDir/#/items
How do I structure my hrefs in the html page? i tried playing around with the ../#/items/ and ..#/items and adding the .. to the other templateUrl but nothing seemed to work. Thanks
so it seems like the simplest solution is to define the routes and hrefs as below. My problem was not having all three of these combinations at once. I thought angular defined the root of the angular routes based on my ~/App/App1 where I defined:
<div class="row" data-ng-app="app-app1">
<div data-ng-view></div>
</div>
so I needed in the app.js:
$routeProvider.when("/", {
templateUrl: "views/app1/index.html"
})
# the top of my _Layout.cshtml
<base href="/app/">
my href:
data-ng-href="App/App1#/items"

AngularJS: What is a modular approach to sidebars and sub-pages?

I'm building an app for fun and practice, and within the app there is a dashboard module. That dashboard module houses other modules. I do this because the dashboard is the parent state for the modules inside of it and I didn't think it would be right to put them in the outside folder with all the other irrelevent modules, because they belong to the dashboard. For example:
/login
/signup
/logout
/profile
/dashboard
/home
/settings
/foo
/bar
...and their states would be dashboard.home with a url of /dashboard/home, and so forth.
In the settings folder, I have a current set up that works, but I don't know if it's considered good practice.
Under the settings directory, I have some partials and controllers. For example:
/login
/signup
/logout
/profile
/dashboard
/home
/settings
/controllers
settingsAccount.controller.js
settingsPassword.controller.js
settingsPersonal.controller.js
/partials
_account.html
_password.html
_personal.html
settings.html
settings.module.js
/foo
/bar
And those partials would be navigated through on the settings.html. How I currently do this is like this..
settings.html:
<div class="row" ng-controller="LeftSidebarController as sidebar">
<div class="col-sm-3">
<div class="page-title">
<h1 view-title>Settings</h1>
</div>
<ul class="list-group">
<li class="list-group-item" ng-class="{'active': sidebar.currentTab(1)}" ng-click="sidebar.setTab(1)">
<a href>Account</a> <i class="fa fa-chevron-right list-group-item__arrow-right"></i>
</li>
<li class="list-group-item" ng-class="{'active': sidebar.currentTab(2)}" ng-click="sidebar.setTab(2)">
<a href>Password</a> <i class="fa fa-chevron-right list-group-item__arrow-right"></i>
</li>
<li class="list-group-item" ng-class="{'active': sidebar.currentTab(3)}" ng-click="sidebar.setTab(3)">
<a href>Personal</a> <i class="fa fa-chevron-right list-group-item__arrow-right"></i>
</li>
</ul>
</div>
<div class="col-sm-7">
<div class="widget-container widget-container--settings fluid-height">
<div ng-if="sidebar.currentTab(1)"
ng-include src="'app/dashboard/settings/partials/_account.html'"
ng-controller="SettingsAccountController as account"></div>
<div ng-if="sidebar.currentTab(2)"
ng-include src="'app/dashboard/settings/partials/_password.html'"
ng-controller="SettingsPasswordController as password"></div>
<div ng-if="sidebar.currentTab(3)"
ng-include src="'app/dashboard/settings/partials/_personal.html'"
ng-controller="SettingsPersonalController as personal"></div>
</div>
</div>
</div>
...and I have a global controller LeftSidebarController, which looks like this:
(function() {
'use strict';
angular
.module('app.controllers')
.controller('LeftSidebarController', LeftSidebarController);
function LeftSidebarController() {
var vm = this;
vm.tab = 1;
vm.setTab = function(tabId) {
vm.tab = tabId;
};
vm.currentTab = function(tabId) {
return vm.tab === tabId;
};
}
})();
So as you can see, I basically just load one of the partials and attach it's controller to it based on which tab is clicked in the sidebar.
Has anyone ever had to do something like this and know a better approach? I'd really appreciate some good guidance, I don't want to make it like this because it seems really messy to me.
I thought having the sub-sub-modules, with a state of something like dashboard.settings.account, with url of /dashboard/settings/account. If I can't find a better approach I'll probably go that route, seems a bit better to me because then everything has it's own state and I will no longer be including multiple files and controllers in a single state. Only problem is I don't know how I'd handle the sidebar yet.
Thanks!
When I build an app using ui-router, I usually structure it this way:
/app
/components
/states
/login
/signup
/logout
/profile
/dashboard
states.module.js
index.html
app.module.js
app.config.js
The components folder is where I put all of my custom directives, services, filters, etc. organized by feature. For example, I might have a notifications sub-folder that contains a service and a directive.
My states folder has a file called states.module.js that would look something like this:
angular.module('app.states', [
'app.states.login',
'app.states.signup',
'app.states.logout',
// etc.
]);
Then each state sub-folder would have a module and all of the files associated with that state. It would also have a {state}.config.js file that adds the state to $stateProvider.
All of that is similar to what you have done (though I wouldn't put controllers and templates in separate folders). The key difference is, in the case of your dashboard state, I would use views.
dashboard.config.js
angular.module('app.states.dashboard')
.config(stateConfig)
;
function stateConfig($stateProvider) {
$stateProvider
.state('dashboard', {
url: '/dashboard/:view',
views: {
'home#dashboard': {
controller : 'DashboardHomeViewController',
controllerAs: 'home',
templateUrl : 'states/dashboard/home.html'
},
'settings#dashboard': {
controller : 'DashboardSettingsViewController',
controllerAs: 'settings',
templateUrl : 'states/dashboard/settings.html'
},
'': {
controller : 'DashboardViewController',
controllerAs: 'dashboard',
templateUrl : 'states/dashboard/dashboard.html'
},
}
)
;
}
I would have files in that folder for each view controller and template, as well as a module file. The main view template file would look something like this:
dashboard.html
<ui-view name="{{dashboard.view}}#dashboard"></ui-view>
Hopefully that answers your question.

Angular and ngRoute; Open in New Window

I'm looking for a way to use ngRouting to open a template in a new window. I have an ng-view div set up in my index page that allows me to populate the data in my central page, but if the user chooses to open a link in a new window/tab, the page comes back 404, since it is expecting to have ngRoute to load it's controllers and templates. Is there any way to allow Angular to handle this option?
Below is my index page
<script type='text/javascript' src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.min.js"></script>
<script type='text/javascript' src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular-route.min.js"></script>
<body ng-controller="routeController" ng-init="init()">
<div id="wrapper" class="page">
<ul id='settingsLink' class='settingsLink' ng-mouseleave="hideSettingsLink()">
<li>Login</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
<div id="viewcontent">
<div ng-view></div>
</div>
</div>
</body>
And here is my routeController config code:
angular.module('myApp').config(function($routeProvider, $locationProvider, $sceDelegateProvider){
$routeProvider
// route for the Login page
.when('/login', {
templateUrl : 'pages/login.html',
controller : 'AuthenticateController'
})
// route for page 2
.when('/page2', {
templateUrl : 'pages/page2.html',
controller : 'Page2Ctrl'
})
// route for page 3
.when('/page3', {
templateUrl : 'pages/page3.html',
controller : 'Page3Ctrl'
});
$locationProvider
.html5Mode(false)
.hashPrefix('!');
});
Let's say I want to open Page 3. If i right-click and try to open in a new tab, my page resolves back to "index.html#!/login", instead of "index.html#!/page3".
If you're using ngRoute in HTML5Mode, you won't have a hash in the URL and the server will think you're trying to access a file when in reality you're getting an Angular view. You need to use hashbang mode to fix this. In the place where you configure your routes (with $routeProvider), add this:
$locationProvider
.html5Mode(false)
.hashPrefix('!');
Now in your links, add the hash:
link

AngularJs one page app ng-view trouble

I am brand new to AngularJs and after following some tutorials I decided to try to implement a one page app into one of my projects. I have it working but I had one question about this code. Could I change what is shown on the first page before they navigate to anything? I don't want it shown on every page just when they first land on it before clicking any links.
var app=angular.module('single-page-app',['ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when('/',{
templateUrl: 'home.html'
})
.when('/about',{
templateUrl: 'about.html'
});
});
app.controller('cfgController',function($scope){
/*
Here you can handle controller for specific route as well.
*/
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="single-page-app">
<div ng-controller="cfgController">
<div>
<nav>
<ul>
<li>Home</li>
<li>About us</li>
</ul>
</nav>
</div>
<br/>
<div ng-view>
<!--
This DIV loads templates depending upon route.
-->
</div>
</div>
</body>
The pages load fine and if I try to add something to the index.html under ng-view it doesn't show up on the page.
You want to put the content to show up when a user first hits your site under in your "home.html" page which is linked to your "/" route for "ng-view". When a user clicks a link, they will be taken to a new route, and the code/ will be replaced by the route they selected.

Resources