How to configure in ui-router a parent/children relationship where siblings coexist in parent page? I can't make child state multiple named views working.
This is my parent page:parent.html:
<div> I have two child pages:
child page1 detail: <ui-view /> and
child page2 detail:<ui-view />.
I need both pages
</div>
I don't know how to or if I should use multiple-named views since multiple named views seem parallel and separable rather than wrapped around by other text like in the code above.
My ui router config:
$stateProvider
.state('parent', {
url: '/parent',
templateUrl: 'parent.html'
})
.state('parent.children', {
url: '/children',
views: {
'child1': {
templateUrl: 'child1.html'
},
'child2': {
templateUrl: 'child2.html'
}
}
});
The unnamed ui-view only allows one child to be plugged in.
See code in
Plunker
The <ui-view>s in your example are incorrect. It's not a self-closing tag and when ui-view is used as the element instead of an attribute directive you need a name attribute to use named views. If you change your parent.html to the following it should work.
<div> I have two child pages:
child page1 detail: <ui-view name="child1"></ui-view> and
child page2 detail:<ui-view name="child2"></ui-view>.
I need both pages
</div>
Related
I'm just trying to setup a boilerplate for angular 1.5.9 with UI Router 1.0.0. I can display my parent state component within the ui-view, however when I nest states within my parent, my components aren't being injected into my ui-view.
This is my index.html
<body ng-app="app">
<ui-view></ui-view>
</body>
This is the main component
<div class="main-container">
<banner></banner>
<div ui-view='ui-view></div>
</div>
It is at this point where in I'm unable to inject anything into the ui-view.
This is my javascript file
$stateProvider
.state('app', {
url: '/',
component: 'main'
})
.state('app.login', {
url: '/login',
views: {
'ui-view': {
templateUrl: './app/login/login.html'
}
}
});
I'm not sure what I'm doing wrong, any help/direction to the right path would be appreciated.
EDIT
Additional Info that might be helpful
When I reference login as a parent state everything works as expected.
The login component is part of a separate module that I've included in my main module.
For nesting one child state in each parent component, there is no need to use named views as you did by adding a value of "ui-view" for the ui-view directive used in your main component template. Those named views are only required when you want to address more than one ui-view. Then you need to reference them by name.
In your sample, you will not see any content because you also don't target the named view correctly. There are some rules on how to address those named views if the named views are defined in a template which is not the root file. In that case you need to be more specific by referencing the ui-view with a "ui-view-name#state" syntax which would mean "ui-view#app" in your case.
But as already mentioned: In your simple case, just leave out the name for the ui-view and replace the views section in your state config with a plain template (or a component reference).
.state('app.login', {
url: '/login',
templateUrl: './app/login/login.html'
});
For details on nesting views, please have a look at the great sample apps in the ui-router docs.
So this one is really strange, I've no explanation as to why it worked the way it did. All I did was change the javascript file to the one below
$stateProvider
.state('login', {
url: '/login',
component: 'main'
})
.state('login.default', {
url: '/default',
component: 'login'
});
Instead of my parent having '/', changed it to '/login'. I'd be keen to know if someone knows the reason behind this behaviour.
$stateProvider
.state('app', {
url: '/',
templateUrl: path/to/main_component.html
})
.state('app.login', {
url: '/login',
views: {
'ui-view': {
templateUrl: './app/login/login.html'
}
}
});
When you are in app.login view(state) ui-view will be checked in its parent states template. If you don't have a template, it doesn't know where to render.
'ui-view':{} is targetted to its parent view.
'ui-view#':{} is targetted to the root component that is index.html
I have one parent view and many child views. Is it possible to specify state for one of this child as for grandchild, but without specifying current child name in state and how?
So, in my configuration I want to have something like this:
.state("parent", {
url: "" // Resulting url is /
})
.state("parent.child", {
url: /ChildUrl // Resulting url is /ChildUrl/
})
.state("parent.{some param}.grandchild", {
url: "" // Resulting url is /ChildUrl/
})
OR How to change one child view with another without changing url in browser without grandchild solution?
Use inside the parent template.
<div class="parentTemplate">
<h1>Parent Title</h1>
<ui-view></ui-view>
</div>
child1 template:
<div class="child1Template">
<h1>Child1 Title</h1>
</div>
child2 template:
<div class="child2Template">
<h1>Child2 Title</h1>
</div>
The state config:
.state("parent", {
url: "",
templateUrl: "templates/parent-template.html"
})
.state("parent.child1", {
templateUrl: "templates/child1-template.html"
})
.state("parent.child2", {
templateUrl: "templates/child2-template.html",
params: { 'child2Param': 'Default' }
})
Going to parent.child1 or parent.child2 will be at / however the <ui-view> directive will be filled with the appropriate child templates. You do not need a URL to navigate between states. Inject $state into the controller with the navigation and use $state.go('parent.child1'). If you need parameters to be passed define them in the params property on each states and invoke the change in states with $state.go('parent.child2', {'child2Param', someObject.withDynamicValue }.
So, finally solved it with removing url parameter in states configuration for parent view and child view which could be represented as a grandchild. It works in way that I need
I'm developing an application where I have the use for a child state. The purpose of making a child state is
To inherit the resolve
To inherit the url base
When I navigate to the child state, the parent state's view and controller is initialized. The child controller isn't initialized at all, and the view isn't showing at all. One thing that I think is weird is that the child view is actually loaded over XHR, but then it never seems to appear.
How can I make the child state's view appear, and the child state's controller initialize with resolves from the parent state?
.state('restaurant', {
url: "/{city:[a-zA-ZåäöÅÖÄ]{2,}}/{restaurantUrl:[a-zA_ZåäöÅÄÖ\-]{2,}}",
views: {
"main": {
templateUrl: "/views/restaurant.html",
controller: "RestaurantCtrl",
resolve: {
restaurant: function($q, $stateParams, RestaurantsSrvc) {
/*Some stuff going on that returns a promise*/
}
}
}
}
})
.state('restaurant.checkout', {
url: "/checkout",
views: {
"main": {
templateUrl: "/views/checkout.html",
controller: "CheckoutCtrl"
}
}
})
Add the <div ui-view="main"></div> to restaurant.html. Populating ui-view elements outside of the parent template is apparently not possible.
Also make sure that there is one ui-view per template with child states. When you have only one place to insert child templates, don't use named views, they are for cases where multiple child views need to be shown at the same time. The sketch in the documentation illustrates this use case nicely.
Also note that by default the parent view is shown when a child state is active, because the ui-view for the child is within the parent template. If you need to hide the parent stuff (or just parts of it) use ng-hide with the $state service as indicated by this answer.
I'm trying to decide on an Angular Structure for my app. I started with the Angular Full Stack Generator.
In UI-Router, you can nest states. It seems logical for me to nest related states. ex: Registration, Registration.form, Registration.confirmation.... but those nested states seem to rely on each child view and parent view being viewed on the same page.
Meaning the parent will have an <ui-view> tag that will insert the child view when called.
Is it possible to have a nested state replace the parent?
Or do I have just make unnested states?
Or is this a case for an abstract state?
There is a working example
Child replacing parent is almost "native" UI-Router solution. Let's have this state definitions:
.state('parent', {
url: "/parent",
templateUrl: 'tpl.html',
})
.state('parent.child', {
url: "/child",
templateUrl: 'tpl.html',
controller: 'ChildCtrl',
})
And this would be the tpl.html, in our case used for both states:
<div ui-view>
<h3>current state name: <var>{{$state.current.name}}</var></h3>
...
</div>
So, what we can see, parent root HTML element, does have attribute ui-view. That means, that this element also plays a role of a target for a child.
Check it in action here
Following this tutorial: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views, i'm able to create an application with multiple views defined in a root template. I need to modify that scheme a bit by putting tabledata and graph to a child view called content. I want my views to look like that:
index.html
<body>
<div ui-view="header"></div>
<div ui-view="content"></div>
</body>
content.html
<div ui-view="tabledata"></div>
<div ui-view="graph"></div>
And my routes looks like that:
# ...
.state('videos',
url: '/videos'
templateUrl: 'content.html'
views:
'tabledata':
templateUrl: 'tabledata.html'
controller: '...'
'sidebar':
templateUrl: 'graph.html'
controller: '...'
)
However, when pointing my browser to /videos, tabledata.html and graph.html templates are not loaded to corresponding views. Everything works great though, if i'll put tabledata and graph views to index.html
I'm sure there is something really wrong with my code but i'm not able to figure out what exactly nor google anything up.
As far as I'm aware you can only have multiple ui-view's in multiple named views, i.e.when you explicitly declare a views property on your state definition. I'm not entirely sure what you're after, but if you would like to have control over where hese ui-views load their states then you can use an abstract state, from the link you provided:
Views override state's template properties
If you define a views object, your state's templateUrl, template and
templateProvider will be ignored. So in the case that you need a
parent layout of these views, you can define an abstract state that
contains a template, and a child state under the layout state that
contains the 'views' object.
This is what I suggest:
.state('videos',{
url: '/videos',
templateUrl: 'content.html',
abstract: true})
.state('videos.xyz',{
url: '/xyz',//you can leave this empty if you like
{
views:{
'tabledata':{
templateUrl: 'tabledata.html'
controller: '...'
},
'sidebar':{
templateUrl: 'graph.html'
controller: '...'
}
}
})
If you don't want that xyz appended to your url's, just pass in an empty string for the url property of the state videos.xyz. I use this approach all the time, let me know if it's what you're after.