AngularJS - how to put side menu html code into external template file - javascript

I'm new to AngularJS. All examples that I have seen so far, have the sidemenu html code in the base index.html file, and not in the templates html partials. I want to move the sidemenu html (as it could become large) into its own template file.
So far the index.html has:
...
<ion-side-menu side="left">
<div ui-view='menu-left'></div>
</ion-side-menu>
...
Then in the app.js I have (and I know this is wrong):
$stateProvider
.state('menu-left', {
url: '/menu-left',
views: {
'menu-left': {
templateUrl: 'templates/menu-left.html'
}
}
})
I see in the browser console the partial file 'templates/menu-left.html' is being loaded. Also if I navigate to ..#/menu-left URL in my app the menu appears. However it should appear on all pages in that spot.
Thanks,

You don't need to create a separate route/state to make use of external HTML templates. As #charlietfl suggests, you can use ng-include to refer to external templates.
Add this line in your index.html
<body>
...
<!-- Note the single quotes within double quotes -->
<div ng-include="'menu-left.html'"></div>
...
</body>
ngInclude documentation
menu-left.html can then have the side menu HTML.
Note that using ng-include leads to additional HTTP calls to fetch the external template. Tempting as it may be to "modularize" the HTML for the navbar, side-menu etc, you may be better off placing the code of core functionality available throughout the web app in a single HTML file to avoid the costs of additional HTTP requests.

Instead of ng-include you could use an abstract parent state and inject the child templates into the ion-nav-view inside parent template.
.state('menu', {
url: '/menu',
abstract: true,
templateUrl: 'templates/menu.html'
})
.state('menu.child', {
url: '/child',
views: {
'menuContent': {
templateUrl: 'templates/child.html'
}
}
});
HTML files: menu.html
<ion-side-menus>
<ion-side-menu>
<ion-nav-bar>
<!-- ion nav buttons -->
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu>
</ion-side-menus>

Related

Where to reference JavaScript files for Ionic's template/[xxx].html

I am trying to reference JavaScript files for my Ionic Mobile Apps project's navigation.html, located inside the www/templates/ directory.
*Note : I created the project using the side menu template in Visual Studio 2015 and the project includes an index.html, and all those html pages located inside the www/templates/ directory are using the index.html, something like master page.
In my navigation.html, I have the following code snippet:
<ion-view view-title="Navigation">
<ion-content>
// my html codes will be stored here
</ion-content>
</ion-view>
I tried to reference the JavaScript files in the index.html but I received some error. So I wanna reference the JavaScript files inside the navigation.html. However, since my navigation.html does not have tags, like , , I created them inside the navigation.html. After modifying the navigation.html and putting the reference for the JavaScript files in the navigation.html, it looked like this.
<!DOCTYPE html>
<html>
<head>
// some js files
</head>
<body>
</body>
However, the javascript files are not loaded in the navigation.html. It is supposed to work as I have tried in notepad++, the same codes, and it worked perfectly. I have tried a couple different things, but cannot get the javascript files loaded in the navigation.html. Does anyone know a way I could make this work? Thanks.
If you want to load files (and plug in) only for some views instead of all your app you can use oclazy (https://github.com/ocombe/ocLazyLoad)
And use like this in your routing:
$stateProvider
.state("index", {
preload: true,
abstract: true, //<-- THIS IS A FATHER VIEW
url: "/index",
templateUrl: "/app/view/template/common/content.html"
})
.state("index.main", {
url: "/main",
templateUrl: "/app/view/template/home/home_new.html",
data: { pageTitle: "Home" },
controller: "HomeController",
controllerAs: "homeCtrl",
resolve: {
loadPlugin: function ($ocLazyLoad) { //<-- HERE YOU CAN LOAD FILES ONLY FOR YOUR ROUTING
return $ocLazyLoad.load([
{
name: "ngTagsInput",
files: ["/app/view/assets/lib/bower/ng-tags-input/ng-tags-input.js"]
},
]);
}
}
})

Multiple master page angularjs

I'm starting a new project and am going to be using angularjs.
The page structure is the follow:
/views
loginView.html
mainView.html
loginMaster.html
mainMaster.html
My problem is set the other master page(mainMater.html) after the login.
The routing function is follow:
mainapp.config(['$routeProvider',function($routeProvider) {
$routeProvider.when('/login', {
controller : 'loginController',
templateUrl : '/views/loginView.html'
}).when('/', {
controller : 'mainController',
templateUrl : '/views/mainView.html'
}).otherwise({
redirectTo : '/login'
});
}]);
AngularJS is great for single page applications, which means if you exit the context of javascript by loading an entirely new page, you'll have to setup the context again. I would recommend you to have just one master page (load the page from the server once and perhaps have something like:)
<html ng-app="myApp">
...
<body>
<div class="container" ng-view>
and keep changing the entire view within the ng-view context. Have the login screen, signed in experience, all of it in the same place.

Login Page without Index.html Design - ngRoute (AngularJS)

I'm using ngRoute to do the routing of my AngularJS application (myApp) but I have a problem: I don't know how to NOT APPLY my index.html design (with all my sidebars) to my login.html page, which seems to be applied by default if it is defined as a view. I want a simple design for my login.html page: only two fields to fill out, without the design of my index.html, which is applied to all the views in myApp. Thereby, I don't know how to do my routing to accomplish such task. Thank you very much.
<-- This is a sample of how I do my routing in myApp (for only one view - "/view1") -->
Sample of app.js:
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'ngResource',
'ui.bootstrap',
'ngCookies',
'myApp.view1',
])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
For each view there is a .js file associated where I defined its routing and controllers. For instance, for view "/view1" - view1.js:
'use strict';
angular.module('myApp.view1', ['ngRoute', 'ngResource'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {
templateUrl: 'view1.html',
controller: 'View1Ctrl'
});
}])
.controller('View1Ctrl', ['$scope', function($scope) {
// something
}]);
And a sample of my index.html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<script src="view1.js"></script>
<-- MORE SCRIPTS ARE LOADED -->
</head>
<body class="hamburg" ng-controller="MasterCtrl">
<-- SIDEBARS ARE DEFINED -->
<div id="content-wrapper">
<div class="page-content">
<!-- Main Content -->
<div class="row">
<div class="col-xs-12">
<div class="widget">
<div class="widget-body">
<div ng-view></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
Given the situation above looks like you want two page layout (page design or page template), the first one is now used in index.html, and the second one you want to use in login.html which just has two fields to fill out. So angular-ui/ui-router (doc url: https://github.com/angular-ui/ui-router/wiki) could be the solution to this issue.
The idea behind that is ui-router has a very powerful tool named ui-view which you can see it as a layout or template. So when the path is on any page other than login page like /index or /home use one ui-view, and on /login page then use another different ui-view.
For a rough example:
index.html page:
<html>
<head></head>
<body>
<div ui-view="layout"></div>
</body>
</html>
I assume you will reuse the head part, so just wrap every thing from the body in the original index.html and put into the new index.html. Same to the login page login.html.
config file:
$stateProvider
.state('index', {
url: '/index',
views: {
layout: {
templateUrl: "/path/to/index.html"
}
},
controller: 'indexController'
}
.state('login', {
url: '/login',
views: {
layout: {
templateUrl: "/path/to/login.html"
}
},
controller: 'loginController'
})
So what does the code above do is very similar to what you did with $routeProvider, it defines on which url use which controller and to load which view.
Hope this can help you, if any question let me know please.
You need to create your login page as a diferente ngApp, store your sesion on the localSotarge in case of a successfull login and then redirect to you main ngApp.
In your main ngApp, validate if a session exists in the localStorage and redirecto to the loginApp if it dont.
I know it sounds a bit like overdoing stuff, but I have not found any other solution in my 3 years working with AngularJS. Now, keep in mind that this is necesary because you need to NOT TO APPLY your index.html, and the only way to do that is using another ngApp.
Routing is used for injecting views in angular SPA. What I get from from your question is you need a login dialog.
For that you may look ngDialog or uibDialog
In your case you need to load new layout. I understand, for login and for application there is mostly different layout. This operation is equal to redirecting page to new location. With new angular app and controllers for login. You can use:
$window.location.href="new/layout/template".
Read more # Angular Dev Docs.

How does one map many routes in AngularJS?

An AngularJS site with a Spring Boot backend has numerous public url patterns in addition to a secure section. All the public url patterns fall in the model mydomain.com/public1, mydomain.com/public2, mydomain.com/public3, and so on, while all the secure content will be inside the mydomain.com/secure url pattern like mydomain.com/secure/one_of_many_urls. The problem is that the sample app I am starting with has separate modules for every route. This would become hard to maintain with n routes.
How can I set the code up so that all the public1, public2, public3, public_n routes share a single controller?
Here is the current directory structure. I would like for the public1 directory to turn into public and be able to map as many specific url patterns as I want to put into it:
In addition, my public1.js is currently empty as follows:
angular.module('public1', []).controller('public1', function($scope, $http) {
});
The link to the public1 route is handled in a navigation bar in index.html as follows:
<!doctype html>
<html>
<head>
<title>Hello Angular</title>
<!-- To produce natural routes (without the #), you need an extra <base/> element in the header of the HTML in index.html, and you need to change the links in the menu bar to remove the fragments ("#"). There are also changes in a spring controller and in the main js module. -->
<base href="/" />
<link href="css/angular-bootstrap.css" rel="stylesheet">
<style type="text/css">
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}
</style>
</head>
<body ng-app="hello" ng-cloak class="ng-cloak">
<div ng-controller="navigation" class="container">
<ul class="nav nav-pills" role="tablist">
<li ng-class="{active:tab('home')}">home</li>
<li ng-class="{active:tab('message')}">message</li>
<li ng-class="{active:tab('public1')}">public1</li>
<li>login</li>
<li ng-show="authenticated()">logout</li>
</ul>
</div>
<div ng-view class="container"></div>
<script src="js/angular-bootstrap.js" type="text/javascript"></script>
<script src="js/auth/auth.js" type="text/javascript"></script>
<script src="js/home/home.js" type="text/javascript"></script>
<script src="js/message/message.js" type="text/javascript"></script>
<script src="js/public1/public1.js" type="text/javascript"></script>
<script src="js/navigation/navigation.js" type="text/javascript"></script>
<script src="js/hello.js" type="text/javascript"></script>
</body>
</html>
And public1.html is:
<h1>Public 1</h1>
<div>
<p>This will be a public url pattern.</p>
</div>
How do I change the code below so that a scaling n number of public routes can efficiently share the same controller? Each public_n route will have their own images, but would share js logic, if they have any js logic.
I found the following, but where would one put it in the code above, and how would a person link everything to it without resorting to leaving it in hello.js?
.when('/public1', {
templateUrl: 'js/public/public1.html'
}
.when('/public2', {
templateUrl: 'js/public/public2.html'
}
.when('/public3', {
templateUrl: 'js/public/public3.html'
})
How do I change the code below so that a scaling n number of public
routes can efficiently share the same controller?
You can Associate one Controller to Many Routes (Views) just assigning it to more routes in your $routeProvider as follows:
myApp.config(function ($routeProvider) {
$routeProvider
.when('/public1', {
templateUrl: 'js/public/public1.html',
controller: 'myController'
})
.when('/public2', {
templateUrl: 'js/public/public2.html',
controller: 'myController'
})
.when('/public3', {
templateUrl: 'js/public/public3.html',
controller: 'myController'
})
.otherwise({
redirectTo: '/'
});
})
You can also Set a Controller Alias as follows:
.when('/public1', {
templateUrl: 'js/public/public1.html',
controller: 'myController',
controllerAs: 'myCtrl'
})
I found the following, but where would one put it in the code above,
and how would a person link everything to it without resorting to
leaving it in hello.js?
If I got your question, you just need to put the $routeProvider in a separated routeProvider.js file and include it in your index.html. Same thing for your controller/controllers.
I suggest you to take a look at:
AngularJS Controllers Documentation
AngularJS $routeProvider Documentation
Follow the first lesson of - CodeSchool - Staying Sharp with AngularJS
EggHead.io AngularJS Screencasts
And also take a look at those Q/A on StackOverflow:
Using one controller for many coherent views across multiple HTTP requests
Views sharing same controller, model data resets when changing view
Controlling multiple views in one controller in AngularJS
Can I use one controller updating two views in AngularJS?
I hope I've been helpful.

AngularJS loading different views through routes

I want to display two pages, but use a base layout. I have it somewhat working with the following:
index.html
<html data-ng-app="myApp">
<head>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
</head>
<body>
<div data-ng-view class="container"></div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="public/app.js"></script>
</body>
</html>
main.html
<div>
<h2> Hello! This is Main page </h2>
</div>
list.html
<div>
<h2> This is List page </h2>
</div>
app.js
var myApp = angular.module('myApp', []);
// Routing Setup
function myAppRouteConfig($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'index.html'
}).
when('/list', {
controller: ListController,
templateUrl: 'list.html'
}).
otherwise({
redirectTo: '/'
});
}
myApp.config(myAppRouteConfig);
This somewhat works when I visit index.html and list.html, but two problems:
When I load index.html, bootstrap loads fine. But when I visit list.html, bootstrap doesn't load. In fact, looking at the html source in firebug, all the code from index.html isn't loaded. The container is missing, the script and css links are missing.
How do I load an actual index page? I have my main.html that I want to load when a user visits the root page, but index.html is the base layout that contains code that persists through all other views (ie, like header and footer etc). If I modify my app.js and set the templateUrl: 'main.html', it seems to still load index.html. Is AngularJS implicitly looking for index.html as the base template?
EDIT:
File structure:
-- server.js
-- public/
|-- index.html
|-- list.html
|-- main.html
|-- js
|-- app.js
Change your route to:
$routeProvider.
when('/', {
templateUrl: 'main.html'
}).
when('/list', {
controller: ListController,
templateUrl: 'list.html'
}).
//if you need to use login page, add 1 more route
when('/login', {
templateUrl: 'login.html'
})
otherwise({
redirectTo: '/'
});
and put your index.html at the root directory (or any sub directory) of your web app, configure it as the default document.
Is AngularJS implicitly looking for index.html as the base template?
There is nothing related to angular here, this is the normal behavior of loading an html page from a web server.
Here is how it works:
When users access your application at the root url (e.x: http://example.com) or any sub directory (http://example.com/public), the index.html is loaded into browser like with normal web applications, then your app.js is run as normal. When the routes are registered and the application is bootstrapped, angular checks the route and loads main.html to be inserted into the container where ng-view is declared.
After digging around, it turns out my AngularJS route requires ngRoute, which is its own module now. After including it, it started to display the correct pages.

Categories

Resources