I am using UI Router for my application. Their FAQ page covers default child state question, but they are not using named views and i can't figure out how to get this working.
Here are samples of my code:
index.html
<a ui-sref="/">Home</a>
<a ui-sref="topic.basics">Basics</a>
<a ui-sref="topic.payments">Payments</a>
<div ui-view="container" class="container"></div>
app.js
$stateProvider
.state("/", {
url: "/"
})
.state("topic", {
url: "/topic/",
abstract: true,
// ?
})
.state("topic.basics", {
url: "basics/",
views: {
"container": {
templateUrl: "views/basics.html"
}
}
})
.state("topic.payments", {
url: "payments/",
views: {
"container": {
templateUrl: "views/payments.html"
}
}
});
$urlRouterProvider
.when("/topic/", "/topic/basics/")
.otherwise("/");
You are almost there, but because the view target is not a parent, but index.html, we have to use aboslute naming
.state("topic.basics", {
url: "basics/",
views: {
// instead of this, which targets the parent
// "container": {
// we need this, where string empty after # means root/index.html
"container#": {
templateUrl: "views/basics.html"
}
}
})
.state("topic.payments", {
url: "payments/",
views: {
// "container": {
"container#": {
templateUrl: "views/payments.html"
}
See
View Names - Relative vs. Absolute Names
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#': { }
}
})
Make the base home state abstract and remove the / in front of the /topic you already use this in the base route.
$stateProvider
.state("home", {
name: 'home',
abstract: true,
url: "/"
})
.state("topic", {
name: 'home.topic',
url: "topic/"
})
.state("topic.basics", {
url: "basics/",
name: 'home.topic.basics'
views: {
"container": {
templateUrl: "views/basics.html"
}
}
})
.state("topic.payments", {
url: "payments/",
name: 'home.topic.payments',
views: {
"container": {
templateUrl: "views/payments.html"
}
}
});
$urlRouterProvider.otherwise("/");
Related
Consider the layout below:
I've got two views, view A and view B. I'm trying to load user menu in A view and menu contents in B view.
I tried this:
First I loaded my menu in A view, then when I tried to view a menu , ui-router will make A view empty and load B view.
How could I hold A view state while B view state is changing?
Perhaps the way I'm doing this is totally wrong.
Update 1:
Here is my route config:
$stateProvider
.state("login", {
url: "/login",
views: {
"login": {
templateUrl: "./static/views/login.html",
controller: loginController
}
}
})
.state("dashboard", {
url: "/dashboard",
views: {
"view-a": {
templateUrl: "./static/views/dashboard.html"
}
}
})
.state("test", {
url: "/test",
views: {
"view-b": {
templateUrl: "./static/views/test.html"
}
}
});
It seems you want B to be a nested view of A. There a few differernt ways to achieve this, here are the docs https://github.com/angular-ui/ui-router/wiki/Nested-States-and-Nested-Views
This approach will give a possible route to view B at /dashboard/test
$stateProvider
.state("login", {
url: "/login",
views: {
"login": {
templateUrl: "./static/views/login.html",
controller: loginController
}
}
})
.state("dashboard", {
url: "/dashboard",
views: {
"view-a": {
templateUrl: "./static/views/dashboard.html"
}
}
})
.state("dashboard.test", {
url: "/test",
views: {
"view-b": {
templateUrl: "./static/views/test.html"
}
}
});
Inside dashboard.html you can reference view-b by having <div ui-view="view-b"></div>
This is a very interesting question where I didn't find any answer.
I have different views like the draw below :
I have the first html file which contains three views i'm using the code below for it :
$stateProvider
.state('home', {
url: '/home',
views: {
day: {
templateUrl: 'home.html',
}
}
})
.state('help', {
url: '/help',
views: {
day: {
templateUrl: 'help.html'
}
}
})
.state('contact', {
url: '/contact',
views: {
day: {
templateUrl: 'contact.html'
}
}
})
and in the html file the container : <ion-nav-view name="day"></ion-nav-view>
then a second HTML file which contains a content and a couple of views like :
.state('c', {
url: '/c',
views: {
view: {
templateUrl: 'composition.html'
}
}
})
.state('h', {
url: '/h',
views: {
view: {
templateUrl: 'resume.html'
}
}
})
and the container in the second html file : <ion-nav-view name="view"></ion-nav-view>
When clicking on any item of any view of the first html it should redirect to the second html file with both views.
What should I really use ??
I tried to do this :
make a racine html file which will consider the two html files as ion-views :
and then make changes on the state provider like this :
$stateProvider
.state('index.home', {
url: '/home',
views: {
day: {
templateUrl: 'home.html',
}
}
})
.state('index.help', {
url: '/help',
views: {
day: {
templateUrl: 'help.html'
}
}
})
.state('index.contact', {
url: '/contact',
views: {
day: {
templateUrl: 'contact.html'
}
}
})
.state('match.c', {
url: '/c',
views: {
view: {
templateUrl: 'composition.html'
}
}
})
.state('match.h', {
url: '/h',
views: {
view: {
templateUrl: 'resume.html'
}
}
})
.state('index', {
url: '/index',
abstract: true,
views: {
index: {
templateUrl: 'first.html'
}
}
})
.state('index.match', {
url: '/match',
views: {
day: {
templateUrl: 'second.html'
}
}
})
what do you think please ??
PLUNKER DEMO
From the understanding of question. Is this what you wanted ? If not, let me know. I'll edit. you needed to call ui-sref="match.h" at home.html , this way your 'resume' would show on page transition.
Plunker
I'm trying to implement something as shown in the Multi-Named-Views wiki page of ui-router. The example is the following:
$stateProvider
.state('report', {
views: {
'filters': { ... templates and/or controllers ... },
'tabledata': {},
'graph': {},
}
})
With my current setup as seen below, the routing is not working. Not sure what I'm doing wrong here?
My current index.html looks like this:
<body>
<div ui-view="anonymous"></div>
<div ui-view="home"></div>
</body>
Then my app.js:
app.constant("AccessLevels", {
anon: 0,
user: 1
});
app.config(["$stateProvider", "$urlRouterProvider", "AccessLevels", function ($stateProvider, $urlRouterProvider, AccessLevels) {
/* ANONYMOUS USERS */
$stateProvider
.state('anon', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.anon
}
})
.state('anon.login', {
url: '/login',
views: {
anonymous: {
templateUrl: 'Client/scripts/app/partials/account/login.html',
controller: 'loginCtrl'
}
}
})
.state('anon.register', {
views: {
anonymous: {
url: '/register',
templateUrl: 'Client/scripts/app/partials/account/registration.html',
controller: 'registerCtrl'
}
}
});
/* AUTHENTICATED USERS */
$stateProvider
.state('user', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.user
}
})
.state('user.home', {
views: {
'home': {
url: '/home',
templateUrl: 'Client/scripts/app/partials/home/dashboard/index.html',
controller: 'homeCtrl'
}
}
})
.state('user.deliveries', {
views: {
'home_content': {
url: '/home/deliveries',
templateUrl: 'Client/scripts/app/partials/home/deliveries/deliveries.html',
controller: 'deliveryCtrl'
}
}
});
$urlRouterProvider.otherwise('/login');
}]);
In general, we can use simplified, so called relative view target names only, if we target the parent. And that is not your case, because
.state('anon', {
abstract: true,
template: '<ui-view/>', // parent contains unnamed view
...
})
.state('anon.login', {
url: '/login',
views: {
anonymous: { // this view is not in parent
So we have to use absolute naming
.state('anon.login', {
url: '/login',
views: {
'anonymous#': { // no we target root
// realtive
'' : { // here we target unnamed parent view
// absolute
'#anon' : { //the same as the line above
A link to doc:
View Names - Relative vs. Absolute Names
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.
My application has 3 'ui-views':
nav#
main#
side#
my states whitin the router are like this:
.state('home', {
url: "/home",
views: {
'nav#': { templateUrl: "views/navigation/main.html" },
'main#': { templateUrl: "views/home/main.html" },
'side#': { templateUrl: "views/home/side.html" }
}
})
this one works fine, all three views are rendered.
.state('home.detail', {
url: "/{id}",
views: {
'side#': { templateUrl: "views/home/side.html" }
}
})
This one works also, only the 'side#' view is updated.
Now for the third route, I want to keep the "nav#" view in the same state, like it is done in the "home.detail" route for the 'main#' and 'nav#' views.
.state('seminar', {
url: "/seminar/{id}",
views: {
'main#': { templateUrl: "views/seminars/main.html" },
'side#': { templateUrl: "views/seminars/side.html" }
}
})
Unfortunately, the 'nav#' view is rendered blank when opening the route. Is there a way to tell angular to not clear the view and keep the content?
I could declare the 'nav#' template, but I was wondering if there is a way around this.
My angular app is routed as following:
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
// Each tab has its own nav history stack:
.state('tab.dotnet', {
url: '/dotnet',
views: {
'tab-dotnet': {
templateUrl: 'templates/tab-dotnet.html',
controller: 'QuestionsCtrl'
}
}
})
.state('tab.sql', {
url: '/sql',
views: {
'tab-sql': {
templateUrl: 'templates/tab-sql.html',
controller: 'QuestionsCtrl'
}
}
})
The above two routes use the same controller but different html pages.
Since both the pages are same, I want to have a single html page in my application instead of two different tab-sql and tab-dotnet pages.
But I will need a differentiation variable to be injected to the controller when selecting the tabs.
Basically I need something like this:
.state('tab.dotnet', {
url: '/dotnet',
views: {
'tab-dotnet': {
templateUrl: 'templates/tab.html',
controller: 'QuestionsCtrl',
type: 'dotnet' // so that i get this type in my Controller
}
}
})
.state('tab.sql', {
url: '/sql',
views: {
'tab-sql': {
templateUrl: 'templates/tab.html',
controller: 'QuestionsCtrl',
type: 'sql'
}
}
})
How to achieve this?
You can pass data to controllers in a state using resolve.
.state('tab.dotnet', {
url: '/dotnet',
views: {
'tab-dotnet': {
templateUrl: 'templates/tab.html',
controller: 'QuestionsCtrl',
resolve: {
type: 'dotnet';
}
}
}
})
.state('tab.sql', {
url: '/sql',
views: {
'tab-sql': {
templateUrl: 'templates/tab.html',
controller: 'QuestionsCtrl',
resolve: {
type: 'sql';
}
}
}
})
https://github.com/angular-ui/ui-router/wiki#resolve