index.html
<div ui-view></div>
test.html is loaded on index.html's ui-view
and inside of test.html
<div ui-view="content"></div>
and tried to load another html files but it's not working
here is my ui-router
.state("index", {
url: "",
templateUrl: "views/index.html",
controller : 'MainCtrl',
controllerAs : 'main'
})
.state("test", {
url: "/test",
templateUrl: "views/test.html",
controller : 'testCtrl',
controllerAs : 'test'
})
.state("test.another", {
url : "another/",
views:{
'content':{
templateUrl :'views/another.html'
}
}
})
so basically what I expect is
<div ui-view>
<!-- test.html -->
<div ui-view="test">
<!-- another.html -->
</div>
</div>
I see two problems:
.state("test.another", {
templateUrl: "views/test.html",
views:{
'another#post':{
templateUrl :'views/another.html'
}
}
})
That first templateUrl isn't required; it's only for views, not states.
Also:
'another#post':{
This means you're targeting a view 'another' in 'post.html'. You neither have a view named 'another', nor a template 'post.html'.
Related
For some reason, routeProvider is not working in my code when I'm clicking on the link. I can't seem to find the error.
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
$routeProvider
.when("/", {
template: "Order Details"
})
.when("/first", {
templateUrl: "first.html"
})
.when("/second", {
templateUrl: "second.html"
})
.when("/third", {
templateUrl: "third.html"
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
show details
show details
show details
<div ng-view></div>
Here is your fix :
Change href="#/first" to href="#!first"
And add to your angular app configuration the following lines:
.config(function ($locationProvider) {
$locationProvider.hashPrefix('!');
}
Here is the working plunkr for the same : Click Here
Since we are defining templateUrl parameter to which we provide the path of template to load, it is creating a difference. If we would have used template parameter to which we provide direct html code to load, then your code will work perfectly.
I am trying to create an angular application.
When the index.html page is loaded 2 links login and register are displayed.
When either login or register is clicked the entire view is replaced by the corresponding view.
1. Register/Login links should stay at the top and the corresponding view should be displayed below after clicking on them.
2. After successful authentication in login controller, The complete view including the login and register link should be replaced with menu-auth.html view.
I have tried using the below code, but still the 2 links disappear and login/register views appear.
Also after the http Post is fired in login controller, the menu-auth.html is displayed but appropriate css is not displayd, so I am not able to click the menu links.
I guess the menu-auth.html view is not placed in the view of index.html
index.html
<!doctype html>
<html>
<head>
<script src = "js/angular.min.js"></script>
<script src = "js/angular-ui-router.min.js"></script>
<script src = "app/app.js"></script>
<script src = "controller/login.js"></script>
<script src = "controller/register.js"></script>
<script src = "app/config.js"></script>
<style>.active { color: red; font-weight: bold; }</style>
</head>
<body>
<div ng-app="app">
<ui-view>
</ui-view>
</div>
</div>
</body>
</html>
I have two views
menu-unauth.html
<a ui-sref="login" ui-sref-active="active">Login</a>
<a ui-sref="register" ui-sref-active="active">Register</a>
<ui-view="unauth"></ui-view>
menu-auth.html
<a ui-sref=".nentry" ui-sref-active="active">Create Entry</a></br>
<a ui-sref=".ventry" ui-sref-active="active">View entry</a></br>
<a ui-sref=".logout" ui-sref-active="active">Logout</a></br>
<ui-view="auth"></ui-view>
config.js
app.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('unauth', {
url:'',
templateUrl: 'view/menu-unauth.html'
})
.state('unauth.login', {
url:'/login',
templateUrl: 'view/login.html',
controller: 'login'
})
.state('unauth.register', {
url:'/register',
templateUrl: 'view/register.html',
controller:'register'
})
.state('auth', {
url:'/menu',
templateUrl: 'view/menu-auth.html'
})
}]);
app.js
var app = angular.module("app", ['ui.router','ngCookies']);
login.js (Controller)
app.controller('login', function($scope,$http,$cookieStore,$state){
$scope.login=function(){
$scope.credentials={
UserName:$scope.email,
Password:$scope.password
};
$http({
method: 'POST',
url: 'test.com/sess',
data: $scope.credentials
}).then(function(response) {
$state.go('auth');
}
}
});
I made the following changes to (observe the ui-sref value changed to contain . dot)
menu-unauth.html
<a ui-sref=".login" ui-sref-active="active">Login</a>
<a ui-sref=".register" ui-sref-active="active">Register</a>
<ui-view></ui-view>
config.js
app.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('unauth', {
url:'',
templateUrl: 'view/menu-unauth.html'
})
.state('unauth.login', {
url:'/login',
templateUrl: 'view/login.html'
})
.state('unauth.register', {
url:'/register',
templateUrl: 'view/register.html'
})
}]);
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 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.
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