Its has been a heavy hours research and applying the techniques however I am not able to solve the issue. My app has three top navigations which are home, sports and country.
<head>
<script src="js/angular-ui-router.min.js"></script>
<script src="js/angular.min.js"></script>
<script src="js/index.js"></script>
</head>
The navigation looks like:
HTML looks like below which is in index.html
<ul>
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="sports">Sports</a></li>
<li><a ui-sref="country">Country</a></li>
</ul>
<div ui-view></div>
In sports.html, there are other three navigation, which are not working (they are not even clickable).
<ul>
<li><a ui-sref="sports.football">Football</a></li>
<li><a ui-sref="sports.weightlifting">Weightlifting</a></li>
<li><a ui-sref="sports.swimming">Swimming</a></li>
</ul>
<div ui-view></div>
Angular looks like
$stateProvider
.state('home', {
url: '/',
templateUrl: 'index.html'
})
.state('sports', {
url: '/sports',
templateUrl: 'sports.html'
})
.state('country', {
url: '/country',
templateUrl: 'country.html'
})
.state('sports.football', {
url: '/football',
templateUrl: 'sports/football.html'
})
.state('sports.weightlifting', {
url: '/weightlifting',
templateUrl: 'sports/weightlifting.html'
})
.state('sports.swimming', {
url: '/swimming',
templateUrl: 'sports/swimming.html'
});
Basically, when a user opens the app, there should be top menu bar with Home, Sports and Country. When a user clicks Sports then there should be another view shown/ another sub navigation in this page showing Football, Weightlifting and Swimming. However these sub navigations are not clickable and not working.
It would be grateful if you can help me to find what would be the problem.
It's a problem of nested views. If you explicitly target the different views you can resolve it.
<ul>
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="sports">Sports</a></li>
<li><a ui-sref="country">Country</a></li>
</ul>
<div ui-view></div> <!-- your sports.html plugs in here -->
In sports.html :
<ul>
<li><a ui-sref="sports.football">Football</a></li>
<li><a ui-sref="sports.weightlifting">Weightlifting</a></li>
<li><a ui-sref="sports.swimming">Swimming</a></li>
</ul>
<div ui-view></div> <!-- your [sportName].html plugs in here -->
So in your app.js, you just have to add some params concerning the nested view in sport.html, like this :
$stateProvider
.state('home', {
url: '/',
templateUrl: 'index.html'
})
.state('sports', {
url: '/sports',
templateUrl: 'sports.html'
})
.state('country', {
url: '/country',
templateUrl: 'country.html'
})
.state('sports.football', {
url: '/football',
// Relatively targets the unnamed view in this state's parent state, 'sports'.
// <div ui-view/> within sports.html
views: {
"": {
templateUrl: 'sports/football.html'
}
}
})
.state('sports.weightlifting', {
url: '/weightlifting',
// Relatively targets the unnamed view in this state's parent state, 'sports'.
// <div ui-view/> within sports.html
views: {
"": {
templateUrl: 'sports/weightlifting.html'
}
}
})
.state('sports.swimming', {
url: '/swimming',
// Relatively targets the unnamed view in this state's parent state, 'sports'.
// <div ui-view/> within sports.html
views: {
"": {
templateUrl: 'sports/swimming.html'
}
}
});
If you want more details, you can read this doc : https://github.com/angular-ui/ui-router/wiki/Multiple-Named-views
There is no issue in your code. Probably you might be missing some dependencies.
Check out my plunker.click here to view code demo
app.js
(function(){
angular
.module('plunker', ['ui.router']);
})();
router.js
(function(){
'use strict';
angular
.module('plunker')
.config(['$stateProvider', function($stateProvider)
{
$stateProvider
.state('home', {
url: '/',
templateUrl: 'home.html'
})
.state('sports', {
url: '/sports',
templateUrl: 'sports.html'
})
.state('sports.football', {
url: '/football',
templateUrl: 'football.html'
})
.state('sports.weightlifting', {
url: '/weightlifting',
templateUrl: 'weightlifting.html'
})
.state('sports.swimming', {
url: '/swimming',
templateUrl: 'swimming.html'
})
.state('country', {
url: '/country',
templateUrl: 'country.html'
});
}])
})();
<li><a ng-click="goTo('sports.football')">Football</a></li>
In Your Controller
$scope.goTo = function(path){
$state.go(path)
}
Related
var app = angular.module("flight", ["login", "chat", "groups", "grpApp", "userApp", "ui.router"])
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/login");
$stateProvider
.state("login", {
url: "/login",
templateUrl: "login.html",
controller: "loginCtrl"
})
.state("chat", {
url: "/chat/:userid/:fname/:lname/:image",
templateUrl: "flightsearch.html",
controller: "flightCtrl"
})
.state("chatGroups", {
url: "/chatGroups/:userid/:fname/:lname/:frmCityCode/:toCityCode/:originCity/:destinationCity/:dateTime",
templateUrl: "groups.html",
controller: "groupsCtrl"
})
.state("chatPage", {
url: "/chatPage/:userid/:fname/:lname/:origin/:destination/:groupname",
templateUrl: "grpChat.html",
controller: "grpChatCtrl"
})
.state("userPg", {
url: "/userPg/:userfbid",
templateUrl: "userPage.html",
controller: "userCtrl",
params: {
userData: null
}
})
});
<body style="background-color:light-grey">
<nav class="navbar navbar-inverse" style="background-color:darkblue;width:100%;margin-bottom:0px">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" style="color:white;height:13%;font-size:25px"><i class="fa fa-paper-plane-o" aria-hidden="true"></i><b>Flight</b>CHAT
</a>
</div>
<span class="glyphicon glyphicon-log-out" style="float:right;color:white;font-size:20px;margin-top:10px;cursor:pointer" ng-click="facebookLogout()" ui-sref="chat"></span>
</div>
</nav>
<ui-view>
</ui-view>
</body>
Iam working with facebook integration in my application.Here I have to login first and then go to another state.There I have to represent logout button for every state.I have declared logout button containing function calling for logout in the page where user re-directed to after login.But where I have to declare that logout function definition.I need it in every state till end.Please help me.Below are index html code and app.js code.
Is there any common controller like header, in that controllr we would like to write down the facebookLogout() fucntion.
Because of the it would be invoke in each and every route,so it will navigate.
$scope.facebookLogout=function(){
// here destroy the session, which has been recently created at the time of login
}
In my js app I have this in config $stateProvider section via angular ui-router:
.state('login', {
url: '/login',
templateUrl: 'app/login/login.tmpl.html',
controller: 'LoginCtrl as login'
})
.state('app', {
abstract: true,
url: '/',
views: {
'main': { templateUrl: 'app/main/main.html' }
}
})
.state('app.reports', {
url: 'reports',
views: {
'': {templateUrl: 'app/templates/reports.tmpl.html'},
'devices#app.reports': {
templateUrl: 'app/templates/devices.tmpl.html',
controller: 'DevicesCtrl as devicesCtrl'
},
'graphics#app.reports': {...}
}
})
In index.html I have:
<body ng-controller="MainCtrl as main" >
<section ui-view>
<div ui-view="main"></div>
</section>
....
</body>
It works only if I have nested ui-view="main" in ui-view.
Is it correct way to work with ui-router?
In main.html I have header, footer and some common information for some pages.
But I have another state, 'login', in which I'll have their own templates. But in index.html their will be loading with ui-view, not ui-view="main".
How can I refactor my index.html and js to avoid nested ui-view in index.html?
Or I have a correct way?
You could refactor your app state like this:
.state('app', {
abstract: true,
url: '/',
templateUrl: 'app/main/main.html'
})
That should allow you to ony have the following in your index.html:
<body ng-controller="MainCtrl as main" >
<section ui-view>
</section>
....
</body>
I m working on angular project and my need is hide header block on login page only. I tried to hide header on login page. But it still doesn't work for me. Can you any one help me to hide it on login state.
Here my index html
<div ng-include src="'views/header.html'" ng-hide="$state.current.name === 'login'"></div>
<div class="">
<div ui-view></div>
</div>
Here my app.js
var app = angular.module('Qapp', ["ui.router", "ngRoute"])
app.config(function($stateProvider, $urlRouterProvider) {
//$urlRouterProvider.when('/dam', '/dam/overview');
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('base', {
abstract: true,
url: '',
templateUrl: 'views/base.html'
})
.state('login', {
url: '/login',
parent: 'base',
templateUrl: 'views/login.html',
controller: 'LogCt'
})
.state('dam', {
url: '/dam',
parent: 'base',
templateUrl: 'views/dam.html',
controller: 'DamCt'
})
});
You don't have access to $state object directly on HTML. For get access to it you should put $state object with the $scope/$rootScope, You could do this in run block/controller & use $state.includes instead of $state.current.name
Markup
<div ng-include src="'views/header.html'" ng-hide="$state.includes('login')">
</div>
Code
app.run(function($state, $rootScope){
$rootScope.$state = $state;
})
I having some problems with the the angular-ui-router. When I click on a ui-sref I get the message
"Error: Could not resolve 'X' from state ''
transitionTo#http:/
Where X is the state in site-header that I'm trying to go to.
I think this means that there isn't a default state, but I'm not sure. In any case here are what I think are the relevant file parts:
index.html
<div class="container" ng-cloak>
<a ui-sref="home"></a>
<div ui-view></div>
</div>
app.config.js
angular.module('fTA')
.config(function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('home', {
url: '/',
template: '<p>This is home view</p>'
});
$stateProvider.state('login' {
url: '/login',
templateUrl: '/views/login.html',
controller: 'LoginCtrl'
});
});
Where /views/login.html are the path names of the files in my directory.
My understanding is that since urlRouterProvider is '/' then I should see <p>This is home view</p> in at '/'. But I don't. So, what retarded thing have I done so that even hard coded templates don't show up.
I just created a plunker here - and change only one thing: added comma after 'login'
$urlRouterProvider.otherwise('/');
$stateProvider.state('home', {
url: '/',
templateUrl: 'tpl.html'
});
// $stateProvider.state('login' {
$stateProvider.state('login', {
url: '/login',
templateUrl: 'tpl.html',
controller: 'LoginCtrl'
});
And this is working now:
<a ui-sref="home">home</a>
<a ui-sref="login">login</a>
The working plunker here
I'm trying to make nested states, but something is wrong and I can't figure out why.
I have these states in my angular app:
/client (list clients)
/client/:id (show client)
/client/new (new client)
And now, I'm trying to do:
/client/:id/task (list clients tasks)
/client/:id/task/new (create new task for this client)
/client/:id/task/:idTask (show the client task)
All the states are working, but the task states is not changing the content.
My index.html with the ui-view "main":
<section id="container">
<header></header>
<sidebar></sidebar>
<section class="main-content-wrapper" ng-class="{'main':collapse}">
<section id="main-content">
<div ui-view="main"></div>
</section>
</section>
</section>
My client.tpl.html with the ui-view "content":
<div class="row">
<div class="col-md-12">
<ul class="breadcrumb">
<li><a href ui-sref="home">Home</a></li>
<li class="active">Clients</li>
</ul>
</div>
</div>
<div ui-view="content"></div>
My app states:
$stateProvider
.state('/', {
url: '/',
templateUrl: '/app/application/application.tpl.html',
abstract: true
})
// CLIENT
.state('client', {
url: '/client',
abstract: true,
views: {
'main': {
templateUrl: '/app/client/client.tpl.html',
controller: 'ClientController'
}
}
})
.state('client.list', {
url: '/list',
views: {
'content': {
templateUrl: '/app/client/client.list.tpl.html',
controller: 'ClientListController'
}
}
})
.state('client.new', {
url: '/new',
views: {
'content': {
templateUrl: '/app/client/client.new.tpl.html',
controller: 'ClientNewController'
}
}
})
.state('client.show', {
url: '/:id',
views: {
'content': {
templateUrl: '/app/client/client.show.tpl.html',
controller: 'ClientShowController',
}
}
})
Tasks states
// TASKS
.state('client.details', {
url: '/:idClient',
abstract: true,
views: {
'content': {
templateUrl: '/app/task/task.tpl.html',
controller: 'TaskController'
}
}
})
.state('client.details.task', {
url: '/task',
views: {
'content': {
templateUrl: '/app/task/task.list.tpl.html',
controller: 'TaskListController'
}
}
})
.state('client.details.task.new', {
url: '/new',
views: {
'content': {
templateUrl: '/app/task/task.new.tpl.html',
controller: 'TaskNewController'
}
}
})
.state('client.details.task.show', {
url: '/:idTask',
views: {
'content': {
templateUrl: '/app/task/task.show.tpl.html',
controller: 'TaskShowController'
}
}
});
So, when I click to go to:
/client
/client/:id
/client/new
Everything works fine, the content change, but, when I click to go to:
/client/:id/task
/client/:id/task/:idTask
/client/:id/task/new
The content don't change, actually, the content gets empty.
UPDATE 1
The link to the task list is in my sidebar, sidebar is a directive:
Directive:
.directive('sidebar', [function () {
return {
restrict: 'E',
replace: true,
templateUrl: '/common/partials/sidebar.html'
};
}])
Template:
<aside class="sidebar" ng-class="{'sidebar-toggle':collapse}" ng-controller="SidebarController as sidebar">
<div id="leftside-navigation" class="nano">
<ul class="nano-content">
<li class="active">
<a href ui-sref="home"><i class="fa fa-dashboard"></i><span>Home</span></a>
</li>
<li class="sub-menu">
<a href ng-click="toggle()">
<i class="fa fa-users"></i>
<span>Clients</span>
<i class="arrow fa fa-angle-right pull-right"></i>
</a>
<ul style="height: {{height}}px; overflow: hidden;">
<li ng-repeat="client in session.clients">
<a href ui-sref="client.details.task({id:client.id})">{{client.name}}</a>
</li>
</ul>
</li>
</ul>
</div>
</aside>
The link in ui-sref is: /client/10/task
Solution there is surprisingly simple, but the concept behind could be a bit challenging.
So the state definition should be like this
Client root state is without any change. It does inject its view into ui-view="main" of the root state (index.html)
// CLIENT
.state('client', {
...
views: {
'main': {
templateUrl: '/app/client/client.tpl.html',
...
}
}
})
Now, we have first level children. They will target ui-view="content" of their parent (client and its template injected into ui-view="main")
.state('client.list', {
views: {
'content': {
....
})
.state('client.new', {
url: '/new',
views: {
'content': {
...
})
...
So until now, everything is working. Below is a change. We try again inject our templates into ui-view="content" - good. But it is not defined in our parent. It is in our grand-parent - a Client state. So we are skipping one level. We have to use absolute naming for view name targeting
// TASKS
.state('client.details.task', {
views: {
// wrong
'content': {
// correct
'content#client': {
})
.state('client.details.task.new', {
views: {
// wrong
'content': {
// correct
'content#client': {
}
})
...
Now it should be clear. If not, maybe this could help a bit. The first level children, would work even with this state definition
.state('client.list', {
views: {
// working
'content': {
// also working
'content#client': {
....
})
Because we just used absolute naming - where the it is done for us out of the box (syntactic sugar). For more and even better explanation, please, see documentation:
View Names - Relative vs. Absolute Names
small cite:
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})