How to refactor separate states and abstract state in UI Router? - javascript

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>

Related

How to make nested views on multiple views in angular ui router?

My app is very simple. i have a home page that contains header and body. in body section I want to show login page and if URL changed to 'password/forget' I show password reset form. my templates:
index.html :
<header ui-view="header">
</header>
<div class="container-fluid">
<div class="row">
<div ui-view="main">
</div>
</div>
</div>
home.html:
<div ui-view>
</div>
And ui-router config is this:
$locationProvider.html5Mode({enabled: true, requireBase: false});
$stateProvider.state('home', {
url: '/',
views: {
'header': {
templateUrl: '/header.html'
},
'main': {
templateUrl: '/home.html'
}
}
}).state('home.forgetPassword', {
url: '/password/forget',
templateUrl: '/forgetPassword.html',
});
Now when I go "/password/forget" anything happen and index.html is showing.
I want to show forgetPassword.html when route changes to "/password/forget" .
Following this code in documentation of ui-router:
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('state1', {
url: "/state1",
templateUrl: "partials/state1.html"
})
.state('state1.list', {
url: "/list",
templateUrl: "partials/state1.list.html",
controller: function($scope) {
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state('state2', {
url: "/state2",
templateUrl: "partials/state2.html"
})
.state('state2.list', {
url: "/list",
templateUrl: "partials/state2.list.html",
controller: function($scope) {
$scope.things = ["A", "Set", "Of", "Things"];
}
});
});
What i suggest is to create the 'password' state first.
Try the following solution:
$stateProvider.state('home', {
url: '/',
views: {
'header': {
templateUrl: '/header.html'
},
'main': {
templateUrl: '/home.html'
}
}
}).state('password', {
url: '/password',
templateUrl: '/password.html',
}).state('password.forgetPassword', {
url: '/forget',
templateUrl: '/forgetPassword.html',
});
Create the file 'password.html' for now, later on it might be useful for '/password' view.
Problem solved. it was for / in parent state and repeat it on child states.

header hide for a particular page in my angular

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;
})

Can't display content page in state with Angular UI Router

I'm beginner in AngularJS and I have a problem when use Angular UI Router.
index.html
<body ng-app="app" ng-controller="AppController" layout="column">
<ui-view></ui-view>
</body>
login.html
<h1>Login page content</h1>
And in my $stateprovider...
.config(function($stateProvider, $urlRouterProvider,$locationProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "views/app.html",
controller: "AppController"
}).state('app.login', {
url: "/login",
templateUrl: "views/login.html",
controller: "LoginController"
});
$urlRouterProvider.otherwise('/login');
})
It can't display a content of login.html page. But when i change state from app.login to login. It can be displayed. How should i do now?
Out of curiosity could you try:
$urlRouterProvider.otherwise('/app/login');
I saw the abstract nested classes routed in that format in some examples,
though i don't have time to test it in jsfiddle.
edit:
Maybe if you try setting the base url to "/" ?
.config(function($stateProvider, $urlRouterProvider,$locationProvider) {
$stateProvider
.state('app', {
url: "/",
abstract: true,
templateUrl: "views/app.html",
controller: "AppController"
}).state('app.login', {
url: "/login",
templateUrl: "views/login.html",
controller: "LoginController"
});
$urlRouterProvider.otherwise('/login');
})

Angular ui-router adding hash to url

I am setting up a scaffold for an app with angular and angular-ui-router. I have it working however it seems to be adding a hash into my url (I'm running dev on localhost) localhost:9000/#/test. When I land on the main page it's just localhost:9000 and it still serves the main view content. I would like to get rid of the hash if possible.
So here is my setup:
In my index.html in the body I just have my nav and then the ui-view under that:
<div class="row">
<ul class="nav navbar-nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="test">Test</a></li>
</ul>
</div>
<div ui-view=""></div>
and in my app.js I just have:
angular
.module('playApp', [
'ui.router'
])
.config(function($stateProvider) {
$stateProvider
.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
});
So when I land, it's fine, but when I start using the nav I have set up, it adds the hashes to the url, would prefer not to have them if possible. Thanks!
Include $locationProvider and do $locationProvider.html5Mode(true); :
angular.module('playApp', ['ui.router'])
.config(function($stateProvider, $locationProvider) {
$stateProvider.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
$locationProvider.html5Mode(true);
});
I also have an otherwise in there as well, so that if it can't find a specified route, it will just default back:
angular.module('playApp', ['ui.router'])
.config(function($stateProvider, $locationProvider, $urlRouterProvider) {
$stateProvider.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
});
Inject $locationProvider into your config and set html5mode to true:
angular.module('playApp', [
'ui.router'
])
.config(function($stateProvider, $locationProvider ) {
$stateProvider
.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
$locationProvider.html5Mode(true);
});
Make sure you adjust your .htaccess to handle this (rewriting back to root).
There is an alternative to html5Mode. But it has its drawbacks.
When defining ui-router states, the url option is not required. From that documentation:
You might create some child states without URLs, if it doesn’t make sense to bookmark those child states. The state machine transitions between url-less states as usual, but does not update the url when complete. You still get all the other benefits of a state transition such as parameters, resolve, and lifecycle hooks.
If you don't need to provide a URL for a state so that users can bookmark those states, you can omit the url option. The URL won't change.

Angular-ui-router doesn't have a default state and can't transition from it

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

Categories

Resources