'update-approved-product-campaign-ad' this is the child state of 'product-campaigns.product-campaign-detail' when i call child state through ui-sref parent state view gets called along with child state view which i don't want. I want only child state view.
i solved this issue by wrapping the parent view with <div ui-view="">
This will override the ui-view with the child when navigating to a child state, otherwise it will contain the patent state's view.
This can be done using view targeting.
Say you have an unnamed ui-view for the parent at the root. When the child is activated, it can take over the parent's unnamed view using targeted views. The child view can put its own content directly into the parent's view:
var app = angular.module("plunker", ['ui.router'])
app.config(function($stateProvider) {
$stateProvider.state('parent', {
url: "",
template: "<a ui-sref='.child'>Go to child</a><h1>Parent</h1>"
}).state('parent.child', {
url: '/child',
views: {
"#": {
template: "<a ui-sref='^'>Back to parent</a><h1>child</h1>"
}
}
})
})
or it could replace the parent view with a template that just has a nested ui-view, which it in turn targets
var app = angular.module("plunker", ['ui.router'])
app.config(function($stateProvider) {
$stateProvider.state('parent', {
url: "",
template: "<a ui-sref='.child'>Go to child</a><h1>Parent</h1>"
}).state('parent.child', {
url: '/child',
views: {
"#": {
template: "<small>parent ui-view overridden by parent.child</small> <div ui-view='child'/>"
},
"child#parent.child": {
template: "<a ui-sref='^'>Back to parent</a><h1>child</h1>"
}
}
})
})
Targeted named views are "viewname#statename". The named view "#" means target the view named empty string ("") at (#) the root state ("").
http://plnkr.co/edit/iff63xbNWCbK9MEPMb4f?p=preview
As far as i know its not possible to load only the child view. Whenever a childs view is loaded, its parents' view is loaded too alongwith it.
Related
My UI includes nested tabs (using Bootstrap). The tab in question is a template with its own controller, currently specified on a view with UI-Router:
.state('editBase.edit', {
url: '/:id',
views: {
'fooTab#editBase.edit': {
templateUrl: 'foo.html',
controller: 'FooController'
},
// more views...
The template uses ng-repeat to create a list of links. Each link goes to an editor child state:
<a ui-sref="editBase.edit.subEdit({itemId: item.id})">{{item.name}}</a>
What I want to happen when the link is clicked is for the contents of the tab (the list) to be replaced with the editor. On clicking a save button, the list would reappear refreshed.
I'm not looking for an in-place editor for a list; I want to hide the entire list, but leave the surrounding templates/tabs intact. In other words, I don't want to replace the root view. How can I do this?
Note: I found this post that explains multiple nested views and view names; this helped me a lot.
In the edit state, create a view that targets the list's <ui-view>
A parent state, just for demonstration. The parent state has a ui-view that the list state plugs into
$stateProvider.state({
name: 'app',
template: '<div ui-view="list"></div>'
});
The list state targets the <ui-view="list">, which was created by the parent state
$stateProvider.state({
name: 'app.list',
url: '/objects',
views: {
list: {
controller: ...
template: `<ul><li ng-repeat="..."></li></ul>
}
}
});
The edit state targets the <ui-view="list"> that was created by the app state. The ui-view was previously filled in by the app.list state. However, the child state's view targeting that ui-view takes precedence over the parent state view.
$stateProvider.state({
name: 'app.list.edit',
url: '/edit/:id',
views: {
"list#app": {
controller: ...
template: "<a ui-sref="^">Go back...</a><form>...</form>"
}
}
}) ;
Here's a working plunker that demonstrates it: http://plnkr.co/edit/Uc39R2ZHUg2Ru3xyEkfe?p=preview
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 new to using Angular UI Router and I seem to be having difficulty being able to update a parent view from it's child view.
I have the following HTML structure (restructured for easier reading, obviously views are in separate html files).
<div ui-view="main">
{ main content }
<div ui-view="tab">
{ tabbed content }
</div>
</div>
Inside tab I have the following sref:
<span ui-sref="silverstone.platforms.view({_id: platform._id})">{{platform.name}}</span>
And here are my states: (I'm using webpack, hence require)
$stateProvider
.state('silverstone', {
url: '/silverstone',
views: {
'main': {
controller: 'SilverstoneCtrl',
template: require('./templates/index.html')
}
}
});
$stateProvider
.state('silverstone.platforms', {
url: '/platforms',
views: {
'tab': {
controller: 'SilverstoneCtrl',
template: require('./templates/platforms.html')
}
}
});
$stateProvider
.state('silverstone.platforms.view', {
url: '/:_id',
views: {
'main': {
controller: 'SilverstoneCtrl',
template: require('./templates/platform-view.html')
}
}
});
When the above sref is clicked, the "main" view needs to be updated. The URL is updating but the views aren't...?
I was missing # in my silverstone.platforms.view state to explicitly address the parent view.
$stateProvider
.state('silverstone.platforms.view', {
url: '/:_id',
views: {
'main#': {
controller: 'SilverstoneCtrl',
template: require('./templates/platform-view.html')
}
}
});
Use reload: true parameter in yout ui-sref links like this.
ui-sref="silverstone.platforms.view({_id: platform._id})" ui-sref-opts="{reload: true}"
Edit:
Maybe your problem are caused by nested states combined with flat template structure.
Other solution may be to properly nest your templates, as states.
For example we have states app and app.substate, then we have two templates for both states. Tempalte of app state contains ui-view directive. (that means every state contains new ui-view directive for injecting of substate template). States are nested by default, this would represent appropriately nested templates.
I have an issue with my Angular UI router configuration.
I have an abstract authenticated state that all of my authenticated pages inherit from. Furthermore, I have a dashboard state that tries to inherit from this authenticated state using the parent: 'authenticated' notation.
Here is my configuration:
.state('authenticated', {
abstract: true,
resolve: {
currentMember: ['$rootScope', '$q', function ($rootScope, $q) {
return $rootScope.authenticated || $q.reject({unAuthorized: true});
}]
}
})
.state('dashboard', {
url: '/dashboard',
controller: 'DashboardCtrl',
templateUrl: 'dashboard/views/dashboard.view.html',
parent: 'authenticated'
})
However, using the above configuration, my dashboard page is always empty...
If I comment out the parent property as follows:
//parent: 'authenticated'
..then the dashboard view is populated with its contents properly...
Can anyone please help?
What we need here is a target for our child view, we need a setting: template: "<ui-view />" in the parent state definition:
.state('authenticated', {
abstract: true,
template: "<ui-view />", // here
resolve: {
currentMember: ['$rootScope', '$q', function ($rootScope, $q) {
return $rootScope.authenticated || $q.reject({unAuthorized: true});
}]
}
})
This template: "<ui-view />", piece of code is now doing essential part of our state machine: it creates target for our child .state('dashboard'.... That state will now be placed (its unnamed view) into that parent target.
The reason why it was working, when we commented out the parent: setting was:
our view of the state 'dashboard' was injected into index.html target <div ui-view=""> - (index.html is so called root state).
The templatce could also be like '<div ui-view=""></div>'. I just used simplified expression resulting in the same behaviour...
To get more ideas about that all, please, check:
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.
...
code snippet cite:
.state('contacts.detail', {
views: {
////////////////////////////////////
// Relative Targeting //
// Targets parent state ui-view's //
////////////////////////////////////
// Relatively targets the 'detail' view in this state's parent state, 'contacts'.
// <div ui-view='detail'/> within contacts.html
"detail" : { },
// Relatively targets the unnamed view in this state's parent state, 'contacts'.
// <div ui-view/> within contacts.html
"" : { },
///////////////////////////////////////////////////////
// Absolute Targeting using '#' //
// Targets any view within this state or an ancestor //
///////////////////////////////////////////////////////
// Absolutely targets the 'info' view in this state, 'contacts.detail'.
// <div ui-view='info'/> within contacts.detail.html
"info#contacts.detail" : { }
// Absolutely targets the 'detail' view in the 'contacts' state.
// <div ui-view='detail'/> within contacts.html
"detail#contacts" : { }
// Absolutely targets the unnamed view in parent 'contacts' state.
// <div ui-view/> within contacts.html
"#contacts" : { }