https://codepen.io/a_shokn/pen/yEJpww?editors=1010
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'main.html'
})
.when('/second',{
templateUrl:'second.html'
})
});
Here is the Link to my Code Snippet , My Question is Were Must we keep our files (in my case main.html and second.html) when using routing in anjular js
As per my understanding, codepen doesn't support adding multiple files. You may try moving your code to plunker instead. Alternatively, you can try to use inline templates in the HTML. For example, to have main.html resolved, you may write this snippet in the HTML:
<script type="text/ng-template" id="main.html">
// contents of main.html
</script>
This will make AngularJS resolve the template using this script tag. You can find a working demo of your code here.
Related
I am using templates to build my app. Basically have one main page, and then I am loading others pages thru it using ng-view. The href links in the index.html work fine. But I also want to be able to change ng-view within js functions as well. How is this done?
I tried to go to the red page using $location.path, but nothing seems to happen besides printing to the console. Before that i tried using $window.location.href(), which did go to the page, but dropped the index.html container, breaking the app.
edit:
As pointed out in Siddhesh's answer comments, it works if not used with $locationProvider.html5Mode(true);. But I would like to keep clean urls. So I'm looking for a way to keep it, IF that's possible.
index.html
<head>
<base href="/testing/onetest/">
<script>
app.controller('masterController',function($location){
setTimeout(change, 3000);
function change() {
console.log("changing in 3 seconds");
$location.path('/red');
}
});
</script>
</head>
<body ng-app="app" ng-controller="masterController">
Main
Red
Green<br>
<div ng-view></div>
</body>
app.js
var app = angular.module("app", ["ngRoute"]);
app.config(function($routeProvider,$locationProvider) {
$routeProvider
.when("/", {
templateUrl : "home.html",
controller : 'mainController'
})
.when("/red", {
templateUrl : "red.html"
})
.when("/green", {
templateUrl : "green.html"
});
$locationProvider.html5Mode(true);
});
For angular js version less than 1.6
$window.location.href= '#red';
For angular js version 1.6 or more
$window.location.href= '#!red';
Try this and see if it works. This might help you to change the ng-view from function. It worked for me.
I have a website by mean-stack.
Normally, all my external references are listed in index.html
I realize that one external JS library (e.g., https://cdnjs.cloudflare.com/troublelibrary.js) I am using has some conflit with a part of my website. So a workaround I am looking for is to NOT load it for a specific path https://www.myexample.com/specific.
Does anyone know how to achieve this in the routing?
Edit 1: (see the full question here)
Actually, the library that has conflit is history.js. My initial code which loads it all the time is as follows. As a result https://localhost:3000/home in a browser is always https://localhost:3000/home (i.e., will not add # because of history.js)
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script src="https://cdn.rawgit.com/devote/HTML5-History-API/master/history.js"></script>
Then, if I try the following code, as Ben suggests:
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
<script>
var newScript = document.createElement('script');
newScript.src = 'https://cdn.rawgit.com/devote/HTML5-History-API/master/history.js';
document.head.appendChild(newScript);
console.log(window.location.href)
</script>
I realize that for the first time of loading https://localhost:3000/home will not change. But, if I refresh the browser, it can change to https://localhost:3000/#/home.
So appending the script is not exactly the same as a direct reference, does anyone know why?
I see your problem in a different perspective. You mentioned that you use the history.js to avoid # on the URL. But you do not need history.js to do that. I think you understood your problem in the wrong way. There is an inbuilt Angular functionality to get rid off # paths. Because # is used to keep track of the relative path on any route. If we want we can override that default functionality.
But if you use this approach the server should responsible to redirect the user to index or home page on any application route since Angular handle all the routing in the application.
First you should add
<base href="/" />
in your HTML file.
Then you should enable HTML5 Mode inside Angular application as follows.
$locationProvider.html5Mode(true);
By adding these two attributes you can get rid off the # path and this is the recommended way.
Following is a complete example.
var app = angular.module("app", ["ngRoute"]);
app.controller("MainController", function($scope){
});
//Add route handler
app.config(["$routeProvider", "$locationProvider", function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
template: '<h1>Home</h1>',
reloadOnSearch: true
})
.when('/about', {
template: '<h1>About</h1>',
reloadOnSearch: true
}).otherwise({
redirectTo: '/'
});
// This will remove hash bang from the routes
$locationProvider.html5Mode(true);
}]);
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.10/angular-route.js"></script>
<base href="/" />
</head>
<body>
<div>
Home
About
</div>
<div ng-app="app" ng-controller="MainController">
<ng-view></ng-view>
</div>
</body>
</html>
As you can see on the above example when you click on the about link the server responds with not found on /about. This means the # bang is removed.
This is one way to do it:
if(window.location.href !== 'https://url.com/path/to/trouble/page'){
var newScript = document.createElement('script');
newScript.src = 'https://url.com/path/to/script';
document.head.appendChild(newScript);
}
Add this to the <head> of the document. It will not load the trouble script on the page you specify in the if statement. Make sure not to load the trouble script anywhere else on the page as well.
you can do lazy loading of script in angular
<script type="text/javascript" ng-src="{{exUrl1}}"></script>
and somewhere in your code (based on whatever logic you want)
$rootScope.exUrl1 = $sce.trustAsResourceUrl(confserver.example.url);
I am learning angular.js and found an example on w3c.school
http://www.w3schools.com/angular/tryit.asp?filename=try_ng_routing
But when I try to test it it doesn't work,
I made two .htm files simply containing one word, for example "RED", or "GREEN". As simple as this example is I cannot get it to work. I think that it might be the libraries I am using
<!DOCTYPE html>
<html>
<!-- JavaScript Files -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-route.js"></script>
<body ng-app="myApp">
<p>Main
</p>
Red
Green
Blue
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider.when("/", {
templateUrl: "test.html"
}).when("/red", {
templateUrl: "red.htm"
}).when("/green", {
templateUrl: "green.htm"
});
});
</script>
</body>
</html>
In this case you are moving towards a page "red.htm" which,... Doesn't exist in your situation! The page is already there in the directory for W3School (http://www.w3schools.com/angular/red.htm for exmaple)
So what you need to do is to create a htm page called red.htm in the same directory and thus navigate to it using routing. If you want to make the same example copy the code of the page I linked and try to run it with both files on the same directory.
From the three files I was using (test.html, red.html, green.html) I finally noticed/understood that you mustn't self-reference the file you are writing the script in.
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider.when("/red", {
templateUrl: "red.htm"
}).when("/green", {
templateUrl: "green.htm"
});
});
</script>
Simply by removing the .when method for 'test.html' (which is the exact same file the code is in) the self-referencing stops, and the code is allowed to execute.
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.
I tried some simple Angular Routing, but I cant specify what's the error. Chrome just tells me that Angular can't compile the Template.
In the following Link you can see my directory structure.
directory-structure
-- angular.js
var testApp = angular.module('testApp', ['ngRoute']);
testApp.config(function($routeProvider){
$routeProvider.when('/list', {
templateUrl: 'pages/list.html',
controller: 'mainController'
}).when('/insert', {
templateUrl: 'pages/new.html',
controller: 'newController'
});
});
testApp.controller('mainController', function($scope){
$scope.message = 'main';
});
testApp.controller('newController', function($scope){
$scope.message = 'new';
});
--index.html
<!DOCTYPE html>
<html lang="en" ng-app="testApp">
<head>
<meta charset="UTF-8">
<title>Barfly</title>
<script src="/angular/angular.min.js"></script>
<script src="/angular-route/angular-route.min.js"></script>
<script src="/js/angularApp.js"></script>
</head>
<body ng-controller="mainController">
list
new
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
This is my error,
Browser Error
Thank you in advance!
EDIT. Sorry, I didn't see your directory structure. Are you sure pages directory is accessible to the public? Should the pages directory be moved into public directory?
Old answer:
The error is saying the templateUrl /pages/list.html does not exists. You should either save a template file into /pages/list.html file or add an inline template in the html body like this:
<script type="text/ng-template" id="/pages/list.html">
my template here
</script>
I encountered a sort of similar problem: templateUrl files could be not loaded (all resources didn't). In my case it happened when app was loaded on a browser on a mobile device. It was caused by Content Security Policy restrictions (How does Content Security Policy work?)
I got the CSP to permit all resources except for the templates referenced by templateUrl.
I also tried loading the templates through the script directive (https://docs.angularjs.org/api/ng/directive/script), but to no avail.
Eventually I decided to embed the templates in the route itself, like this:
testApp.config(function($routeProvider){
$routeProvider.when('/list', {
template: '<li ng-repeat="etcetera"></li>',
controller: 'mainController'
});
});
<a data-target="#list">list</a>
<a data-target="#insert">new</a>