I am trying to make a webpage.In that when a user login , a new html page("dashboard.html")opens in the view. This "dashboard.html" contains some links(links to other html pages).When user clicks on them a new html(say "page_3.html") page should open with data that is present in controller.this "page_3.html" is not fetching data from controller.Below is my code.
<!-- controller.js -->
var app = angular.module('myApp',[ 'ngRoute' ]);
app.config(function($routeProvider){
$routeProvider
.when('/',{
templateUrl: 'login.html'
})
.when('/dashboard',{
templateUrl: 'dashboard.html'
})
.when('/page_3',{
templateUrl: 'page_3.html'
})
.otherwise({
redirectTo : '/'
});
});
app.controller('app', function($scope, $location){
$scope.item = "test";
$scope.submit = function(){
$location.path('/dashboard');
}
};
});
<!DOCTYPE html>
<html>
<head>
<title>Project</title>
<script src="angular.js"></script>
<script src="angular-route.js"></script>
<script src="controller.js"></script>
</head>
<body ng-app= "myApp" ng-controller="app">
<div ng-view></div>
</body>
</html>
<!-- below is login.html page -->
<div ng-controller="app">
<form action="/">
<button type="button" ng-click="submit()">Login</button>
</form>
</div>
<!-- below is my dashboard.html page -->
<div ng-controller="app">
<h1>Page_3</h1>
<div><a href='page_3.html'>page_3</a></div>
</div>
<!-- below is page_3.html page -->
<div ng-controller="app">
<p>{{item}}</p>
</div>
result : {{item}}
May I suggest avoiding the ng-controller directive and rather use the controller config object on your router?
.when('/page_3',{
templateUrl: 'page_3.html',
controller: "app"
})
There are two main problems with your code:
Enable HTML 5 mode for pushState via $locationProvider for URLs like /dashboard and /page_3
Fix the problem where route is configured for /page_3 but having a a tag pointed to /page_3.html
To get a working example:
Add a base tag
<base href="/">
Enable html5 mode via locationProvider in a config block
$locationProvider.html5Mode(true);
Fix route in dashboard.html
<!-- below is dashboard.html page -->
<div ng-controller="app">
<h1>Page_3</h1>
<div><a href='page_3.html'>page_3</a></div>
</div>
Click here for the demo / jsbin.
Other/suggestions: as Zack Briggs have suggested; using controller syntax in routes would help you come up with better code structure / design in router config, directives, or components. Also putting everything in one place is often a bad idea for a growing project.
Related
I have an angular.js app where the index.html looks something like with ng-app in the <html> tag
<html lang="en" ng-app="app">
<head></head>
<body>
<custom-navbar-directive></custom-navbar-directive> //angular js directive
<custom-loader></custom-loader>
<!-- To render components -->
<div ui-view ng-cloak></div>
</body>
</html>
I was following the steps in the single-spa angular.js guide. I removed the ng-app from <html> tag and added the following in my app.js
System.register([], function (_export) {
return {
execute: function () {
_export(
window.singleSpaAngularjs.default({
angular: angular,
mainAngularModule: "app",
uiRouter: true,
preserveGlobal: false,
})
);
},
};
});
Also I did the import map and singleSpa.registerApplication steps in the index.html
My issue is now the content is rendering but the <custom-navbar-directive> and <custom-loader> are missing. I added them inside the index.html since they are commonly used in each html template.
When I inspect and checked the rendered html I noticed that they are outside the loaded single spa angularjs app
<custom-navbar-directive></custom-navbar-directive>
<custom-loader></custom-loader>
<div id="single-spa-application:legacyAngularApp">
<div id="__single_spa_angular_1" class="ng-scope">
<!-- content -->
</div>
</div>
I guess since they are directives if those are inside the <div id="__single_spa_angular_1" class="ng-scope"> then it should render.
Any idea how to solve this?
In my application i have declared ng-app in Master.html and added all script, stylesheet references in it
this is my master page
<html ng-app="mainApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>AdminLTE 2 | Dashboard</title>
<script src="../Angular/angular.min.js"></script>
<script src="../Angular/angular-route.js"></script>
<script src="../Scripts/AngularServices/App.js"></script>
</head>
<body class="hold-transition skin-blue sidebar-mini">
<li><i class="fa fa-circle-o"></i>Group</li>
<li><i class="fa fa-circle-o"></i>Member</li>
<section class="content">
<div ng-view></div>
</section>
</body>
</html>
App.js
var mainApp = angular.module("mainApp", ['ngRoute'])
mainApp.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/main/Group', { templateUrl: '/Portal/Group.html', controller: 'GroupController' }),
$routeProvider.when('/main/Member', { templateUrl: '/Portal/Member.html', controller: 'MemberController' });
$locationProvider.html5Mode(true);
});
// group
mainApp.controller('GroupController', function ($scope, $http) {
$http.get('/api/APIGroup/GetGroupDetails').then(function (result) {
$scope.group = result.data;
});
});
Group.html
<div ng-controller="GroupController">
<div class="row">
<h1>Welcome to group</h1>
my content here
</div>
</div>
when i execute master page and if click group link group.html form opening inside master page my url like this
http://localhost:50810/main/chitGroup
but if reload page here am getting error as
Server Error in '/' Application.
The resource cannot be found.
Master page not applying to how to fix this
In your angular.app you have ngRoute to handle your states for create Single Page Application.
ngRoute need to pass the state names correctly as ng-href="#!/main/Group", that because when you use ngRoute the url changed automaticly to http://localhost:50810/#!/
Server Error in '/' Application.
The resource cannot be found.
This error because you redirect to http://localhost:50810 to find /main/Group which not exist.
My app shows an HTML page with multiple views, and each view can be conditionally built from multiple HTML templates.
I want to edit each HTML file and add a few lines at the top, something like
<div ng-if="showFileNames”>
<hr>
<p>Start of file {{how do I get the file name}}</p>
<hr>
</div>
And maybe the same at the footer.
Thus, by setting $scope. showFileNames to true, I could switch the display of file names on/off and see how my page is actually composed (is this clear, or should I add some ascii art?).
I could just hard code {{how do I get the file name}} in each file, but doing it dynamically means that I can more easily add the code to each file, plus it guards against files being renamed.
Can it be done? If so, how?
[Update] I just realized that the question didn't explain well enough. Sorry.
I need to stress that part where I said
each view can be conditionally built from multiple HTML templates
While the view is state based, its contents are built from different <ng-include> files, based on data.
So, state A might include A.html, but, based on the data, that view might <ng-include> B.html, C.html and E.html, or it might <ng-include> F.html, G.html and H.htFl - and I want to show the file name of each at the head & foot of the part of the view shown by each file
Update: You may have templates loaded with ui-view and ng-include. The example given bottom of this answer has a nice generic directive to return the corresponding template name even though if you nested ui-view and ng-include together. Click through "Home", "About" and "Named View" link inside "About".
Few theory goes below,
If you use ui-view then you can try this with $state.current.templateUrl as below.
<div ng-if="showFileNames”>
<hr>
<p>Start of file {{$state.current.templateUrl}}</p>
<hr>
</div>
The above will work if you had defined your state as below,
.state('state1', {
url: '/state1',
templateUrl: 'partials/state1.html'
controller: 'State1Ctrl'
})
But if you had defined this as named views as below,
$stateProvider
.state('report',{
views: {
'filters': {
templateUrl: 'report-filters.html',
controller: function($scope){ ... controller stuff just for filters view ... }
}
}
}
})
Then, better you can have a method assigned with the $rootScope as below and pass the $state.current.views from the html to the function.
$rootScope.getTemplate = function(view) {
var keys = Object.keys(view);
if(keys.length === 0) return '';
return view[keys[0]].templateUrl;
};
and the html,
<div ng-if="showFileNames”>
<hr>
<p>Start of file {{getTemplate($state.current.views)}}</p>
<hr>
</div>
But you can have a look at the below generic directive which covers ui-view, nested ui-view, named ui-view and ng-include and even a bit of complex nesting with ui-view and ng-include.
Generic directive with an example page
Click through "Home", "About" and "Named View" link inside "About"
var app = angular.module('app', ['ui.router']);
app.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html',
controller: 'TestController'
})
.state('about', {
url: '/about',
templateUrl: 'about.html',
controller: 'TestController'
})
.state('about.named', {
url: '/named',
views: {
'named': {
templateUrl: 'named.html',
controller: 'TestController'
}
}
});
}
]);
app.controller('TestController', function($scope) {
});
app.directive('templateName', ['$state', function($state) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var templateName = $state.current.templateUrl;
var includesParent = $(element).closest('[ng-include]');
if(includesParent && includesParent.length > 0) {
if(includesParent.find('[ui-view]').length === 0) {
templateName = scope.$eval(includesParent.attr('ng-include'));
}
}
if(!templateName && $state.current.views) {
var uiViewParent = $(element).closest('[ui-view]');
var viewName = $state.current.views[uiViewParent.attr('ui-view')];
if(viewName) {
templateName = viewName.templateUrl;
}
}
element.html(templateName);
}
};
}]);
angular.bootstrap(document, ['app']);
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.min.js"></script>
<div>
<!-- NAVIGATION -->
<nav class="navbar navbar-inverse" role="navigation" ng-include="'nav.html'">
</nav>
<!-- MAIN CONTENT -->
<div class="container">
<!-- THIS IS WHERE WE WILL INJECT OUR CONTENT ============================== -->
<div ui-view></div>
</div>
<script type="text/ng-template" id="home.html">
<h3>Home Page</h3>
<p>Start of file: <span template-name></span></p>
</script>
<script type="text/ng-template" id="about.html">
<h3>About Page<h3>
<p>Start of file: <span template-name></span></p>
<div ng-include="'aboutUs.html'"></div>
</script>
<script type="text/ng-template" id="aboutUs.html">
<h3>About us<h3>
<p>Start of file: <span template-name></span></p>
<a ui-sref="about.named">Named View</a>
<div ui-view="named"></div>
</script>
<script type="text/ng-template" id="named.html">
<h3>Named View<h3>
<p>Start of file: <span template-name></span></p>
</script>
<script type="text/ng-template" id="nav.html">
<div class="navbar-header">
<a class="navbar-brand" ui-sref="#">Start of file: <span template-name></span></a>
</div>
<ul class="nav navbar-nav">
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="about">About</a></li>
</ul>
</script>
</div>
I am using ngRoute.
index.html :
<body ng-app="mainApp" ng-controller="AboutController">
<div id="header">
<h1>Employee Gallery</h1>
</div>
<div id="leftpanel">
<!--a href="#/displayEmp" id="load">Display</a><br-->
Display<br>
Insert<br>
Delete
</div>
<!-- Angular dynamic content-->
<div ng-view id="section">
</div>
main.js :
var app = angular.module('mainApp',['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/display', {
templateUrl: 'pages/display.html',
controller: 'DisplayController'
})
.when('/', {
templateUrl: 'pages/about.html',
controller: 'AboutController'
});
/*.otherwise({
redirectTo: '/'
});*/
});
app.controller('AboutController', function($scope) {
console.log("In AboutController");
$scope.msg = "This app performs CRUD operations";
});
If ng-app="mainApp" is specified in the body tag of index.html as shown, 'In AboutController' is printed twice.
If ng-app="mainApp" is moved to
then it is printed once, as should be.
In both cases, output is the same.
1) But need to understand why the controller is executed twice in one case and once in the other.
2) In display.html, console.log is not getting printed within tag.
You're running the ctrl code twice. Once in the <body> tag and another in the route definition. You don't need to define ng-controller="AboutController" in <body>, the router is going to do that for you in your template html, which is templateUrl: 'pages/about.html' for that route.
When using the router you don't need to explicitly set an ng-controller directive on an html element like you have above, the router declares it for you.
<body ng-app="mainApp">
<div id="header">
<h1>Employee Gallery</h1>
</div>
<div id="leftpanel">
<!--a href="#/displayEmp" id="load">Display</a><br-->
Display<br>
Insert<br>
Delete
</div>
<!-- Angular dynamic content-->
<div ng-view id="section"></div>
</body>
Further reading: Combating AngularJS executing controller twice
I am playing around with adding in an Angular-UI router which is working perfectly when I click on links within my application. For example, if I go from / to /feed/9 it will load in the /partials/post.html file into the ui-view div and I can then use the '9' held in $stateParams to populate the template with the data from post 9. However if I refresh the page, the site breaks and Angular tries to load index.html as the ng-app.js file? I have no idea what is happening here. I've uploaded some screenshots to demonstrate this and I've included my node server, angular routing and the relevant html partials. I have no idea where this is going wrong so I can provide any additional data and any help would be greatly appreciated!
Working fine when coming from another link on '/'
On refresh!!
Node - server.js
var = /* Dependencies and vars */;
mongoose.connect(dbConfig.url, dbConfig.options);
app.use(express.static(__dirname + '/public'));
app.use(morgan('dev'));
app.use(bodyParser());
app.use(flash());
require('./routes/api.js')(app); //For CRUD operations on the database
require('./routes/api_proc.js')(app); //Protected endpoints for CDN
require('./routes/api_ext.js')(app); //For getting data from GCal, fb, Twitter and Instagram
/* The following code is a url rewrite to pass all
further get requests that aren't defined in the
above routing files through the index page and
hence through the Angular 'frontend' routes */
app.use(function(req, res) {
res.sendFile(__dirname + '/public/index.html');
});
app.listen(port);
Angular ng-app.js
var app = angular.module('app', ['ui.bootstrap', 'ngResource', 'ui.router']);
//Using state ui-router
// ROUTES
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url : '/',
templateUrl : 'partials/home.html'
})
/* ... */
.state('feed', {
url : '/feed',
templateUrl : 'partials/feed.html'
})
.state('post', {
url : '/feed/{id:.*}',
templateUrl : 'partials/post.html',
controller: 'postController'
})
$locationProvider.html5Mode(true);
});
app.factory("Feed", function($resource) {
return $resource("/api/feed/:id", {}, {
query: {
isArray: true
}
});
});
app.controller("postController", function($scope, Feed, $stateParams) {
var feed = Feed.query();
feed.$promise.then(function(promiseData) {
postArray = promiseData.slice(0,promiseData.length);
$scope.feed = promiseData;
$scope.id = $stateParams.id;
});
});
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<!-- CDN -->
<!-- Angular, Bootstrap, Angular modules, etc. -->
<!-- Styles -->
<!-- Angular Script import -->
<script type="text/javascript" src="ng-app.js"></script>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<nav><!--Bootstrap nav--></nav>
<div ui-view></div>
<footer></footer>
<script>
//For Bootstrap tooltips which are in some of the partials.
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
$('[rel=tooltip]').tooltip();
});
</script>
</body>
</html>
/partials/post.html
<div class="container-fluid main-content">
<header class="banner" class="row">
<h1 class="page-title">{{id}}</h1>
</header>
<!-- Main page info -->
</div>
I think you have relative paths pointing to your css files.
When you load page from /feed/9 then links are invalid.
Maybe it happens also for templates referenced from angular.