I am using ui-sref for routing depending upon state.
Currently I am getting child's view inside parent as hierarchy. I want to assign a child's view to a parent view. Current state is as below plunker.
[link][//plnkr.co/edit/fpsTWglicbcGMotJIlll]
I want to see welcome after clicking click me.
If I understood your question correctly, the problem is you have inner as a child of tab1... so it is displayed in the ui-view of tab1. If you want it instead to make it replace tab1, then you don't need the ui-view in tab1.
Here's a forked plunker showing what I mean.
http://plnkr.co/edit/t4cxejVLGf4kywKp2bb5?p=preview
The parts I changed:
.state("main", { abtract: true, url:"/main", templateUrl:"main.html" })
.state("main.tab1", { url: "/tab1", templateUrl: "tab1.html" })
.state("main.inner",{
url:"/inner",
templateUrl:"inner.html"
})
.state("main.tab2", { url: "/tab2", templateUrl: "tab2.html" })
And in tab1.html
<div>
This is the view for tab1
<a ui-sref="main.inner">click me</a>
</div>
Is this what you're shooting for?
Add $scope.$state = $state;in the controller.
Then add ng-hide="$state.current.name === 'main.tab1.inner'" to
<h2 ng-hide="$state.current.name === 'main.tab1.inner'">View:</h2>
and
<div ng-hide="$state.current.name === 'main.tab1.inner'">
This is the view for tab1
<a ui-sref="main.tab1.inner">click me</a>
</div>
Here's the link [link] http://plnkr.co/edit/Yvlp6RNF69yiSq1HfMcf?p=preview
Related
I am working with ui-router AngularJS in Ionic Project. I have an abstract state where I nest my children's templates via <ion-nav-view> tag. The question is can I display some default data in the template of the abstract state that will be shown for all the children's templates ?? If no then Why. I tried this simple example
<ion-view view-title="MyView">
<div>
<h1>Welcome</h1>
</div>
<ion-nav-view name="ChildContent"></ion-nav-view>
</ion-view>
But the message Welcome is not shown. The space for the div is there but nothing is displayed.
I think I found the solution. What I ended with to not repeat the same info within all the children templates is to create a custom directive with its own template and just include this directive in every child's template. So, we just have one place to manipulate. It is the section "Template-expanding directive" in Angular documentation. More informations could be found in this link : enter link description here. Hope it will help someone else :) .
You can define a controller for your abstract state and there setear default values that can be displayed in various other views. You can also do this in the function
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.controller('AppCtrl', function($scope){
$scope.title = "Test title";
})
OR
angular.module('started.controllers', [])
.run(function($window, $rootScope) {
$rootScope.title = "Test title";
});
<ion-view view-title="{{title}}">
<div>
<h1>Welcome</h1>
</div>
<ion-nav-view name="ChildContent"></ion-nav-view>
</ion-view>
I'm REALLY frustrated right now. I try to change the state in my ionic app for more than 5 hours now.
Here is what I have.
$stateProvider
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.issues', {
url: '/issues',
views: {
'tab-issues': {
templateUrl: 'templates/tab-issues.html',
controller: 'IssuesController'
}
}
})
.state('tab.issue-detail', {
url: '/issues/:vertragsNr',
views: {
'tab-issues': {
templateUrl: 'templates/issue-details.html',
controller: 'IssueDetailsController'
}
}
})
.state('tab.issue-steps', {
url: '/issues/:vertragsNr/steps',
views: {
'tab-issues': {
templateUrl: 'templates/issue-steps.html',
controller: 'IssueStepsController'
}
}
})
when I open the url http://localhost:8100/#/tab/issues/1/steps manually in the browser everything is fine the controller get loaded and everything works as expected.
But when I do
$scope.goto = function(){
$state.go('tab.issue-steps','{vertragsNr:1}')
}
in the IssueDetailsController I see a transition and the IssueStepsController gets loaded but the view doesnt change.
I also tried to do a
ui-sref="tab.issue-steps({ vertragsNr: r.vertragsNr})"
but when I click the button nothing is happening. I see that in the source of the page an href="#/tab/issues/1/steps" gets created on the element but it doesnt change the view.
I also tried
.state('tab.issue-steps', {
url: '/steps',
views: {
'tab-issues': {
templateUrl: 'templates/issue-steps.html',
controller: 'IssueStepsController'
}
}
})
but it still isnt redirecting.
I also tried:
$location.url("tab/issues/1/steps");
which also isnt working
I dont understand why it has to be so complicated to JUST CHANGE A SIMPLE VIEW!
I dont want any subviews in the details view. I just want to open the steps view.
Ok, to clarify, I need to load the steps view into the tabs-issues view which is the content of my tab-control and this is not working from a subview.
I made a plunker with the issue: http://plnkr.co/edit/YK7Fp3vUhEPGZeYtOF9Y?p=info
strange thing is on the second click everything work on the plunker. But the code is exactly the same code as in my application.
I've noticed in that plunker you're still referencing an old version of the framework:
<script src="http://code.ionicframework.com/1.0.0-beta.5/js/ionic.bundle.min.js"></script>
I would change that to the latest stable release:
<link href="http://code.ionicframework.com/1.1.0/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.0/js/ionic.bundle.min.js"></script>
Then you have to fix the view issue-details.html. You have something like this in that html view:
<div class="list card" ui-sref="tab.issue-detail({ vertragsNr: r.vertragsNr})">
....
</div>
you don't really need
ui-sref="tab.issue-detail({ vertragsNr: r.vertragsNr})"
cause it's basically pushing the page back when redirecting.
Just remove it so that your view looks like this:
<ion-view view-title="Ausgaben">
<ion-content class="padding">
<div class="list card">
<div class="item item-divider">{{r.title}}</div>
<div class="item item-body">
<div>
<div><b>Vertragsbeginn:</b> {{r.rentalBegin}}</div>
<div><b>Objekt:</b> {{r.objekt}}</div>
<div><b>Abholer:</b> {{r.abholer}}</div>
<div class="list">
<button class="item item-icon-left" ng-click="goto()" ng-repeat="m in r.machines" ng-disabled="m.abgabeDatum!==null">
<i class="icon balanced" ng-class="{'ion-checkmark': m.abgabeDatum!==null}"></i>
{{m.title}}
</button>
</div>
</div>
</div>
</div>
</ion-content>
</ion-view>
and everything should work as expected.
PS: I've removed hide-nav-bar="true" directive in the view issue-steps.html just to make sure that the navigation works properly. It works anyway even if you add it back.
PPS: As you might have noticed there are a few differences in the way the app looks with the new version 1.1.0 of the framework.
A few things have changed since the beta.
.state("newUtilities", {
url: "/newUtilities",
templateUrl: "app/admin/modules/newUtility/view/newUtilities.html",
controller: "NewUtilitiesController",
resolve: load(['myProject.newUtilities'])
})
I have the following state.
.state('categories', {
url: '/categories',
templateUrl: 'categories',
controller: 'CategoriesController',
})
And template url loads:
<div>
<a ui-sref="categories.bob">my link text</a>
</div>
But ui-sref isn't compiled. How is the right way to slove this case ?
--[EDIT]--
I mean html loaded form template is not compiled by AnulgarJS. For example
<a ui-sref="categories.bob">my link text</a>
should be
<a ui-sref="categories.bob" href="#/categories/bob">my link text</a>
I assume you want to pass bob as an optional parameter? If that is the case try the following:
Defining a new state:
.state('categories.name', {
url: '/:name',
templateUrl: 'subcategorytemplate',
controller: 'SubCategoryController',
})
The route:
<div>
<a ui-sref="categories.name({name:"bob"})">my link text</a>
</div>
You will find your route parameter in ui-router's $stateParams service by calling $stateParams.name. For further information look here.
In fact i found my problem. My nasted state url's was wrong.
.state('categories.category', {
url: '/:category',
templateUrl: function($params) {
console.log($params);
return 'categories/' + $params.category;
},
})
But I still don't understend how and why <a ui-sref="someUrl"> are rendered like <a ui-sref="someUrl" href="#>someUrl"> buy if I load html with templateUrl no href attribute is generated. So is there a way to make it generate href attribute too ?
How to load my nested view in parent ui-view ?
$stateProvider
.state('dashboard', {
url:'/dashboard',
controller: 'MainCtrl',
templateUrl: 'views/dashboard/main.html'
})
.state('dashboard.exchange',{
templateUrl:'views/dashboard/exchange.html',
controller: 'ExchangeCtrl',
url:'/exchange/{exchangeId:[0-9]}',
})
.state('dashboard.exchange.module',{
templateUrl:'views/dashboard/exchangeModule.html',
controller: 'ExchangeModuleCtrl',
url:'/module/{exchangeModuleHostName}',
})
'/dashboard' correctly correctly routes to MainCtrl
'/dashboard/exchange/1' correctly routes to ExchangeCtrl
'/dashboard/exchange/1/module/ae38596496d3' incorrectly routes to ExchangeCtrl
Why doesn't the third url route to ExchangeModuleCtrl? How do I fix this?
In case, that we want last child state: 'dashboard.exchange.module' to totally replace the content of its parent 'dashboard.exchange', we have to options:
First option, whole parent is a target
We can place ui-view="" into the parent root <element>. There is a working example. And this would be the 'dashboard.exchange' state template views/dashboard/exchange.html:
<div ui-view="">
<h3>dashboard.exchange</h3>
<br />
context just for the state: <b>dashboard.exchange</b>
</div>
The most important is the root <div ui-view="">, because child will totally replace parent.
Second approach, target grand parent
In this case, we will skip parent. We will directly target grand parent 'dashboard'. There is a working plunker. Here we use absolute naming to target grand parent unnamed view:
.state('dashboard.exchange.module',{
views : {
'#dashboard' : {
templateUrl:'views/dashboard/exchangeModule.html',
controller: 'ExchangeModuleCtrl',
},
},
url:'/module/{exchangeModuleHostName}',
})
Check these similar Q & A for more details about absolute naming:
Angularjs ui-router not reaching child controller
Angular UI router nested views
Original part of the answer
If we want to follow standard approach - There is a working example
Your code should be workig as is.
The most important is, that each parent must contain target for a child: ui-view="", e.g.:
<div ui-view=""></div>
The view views/dashboard/main.html must contain a target for child state 'dashboard.exchange'
<div >
<h2>dashboard</h2>
<br />
<div ui-view=""></div> // this is for child exchange
</div>
The view views/dashboard/exchange.html must contain a target for child state 'dashboard.exchange.module'
<div >
<h3>dashboard.exchange</h3>
<br />
<div ui-view=""></div> // this is for child module
</div>
Check it here
I have an Angular (1.2.1) app running UI-router (0.2.13), and the following state structure:
$stateProvider.state('home', {
template: "<div home></div>",
url: '/'
}).state('home.geo', {
url:'/geo/{geo}'
}
Transitioning from parent to child or between children with different {geo} parameter values works as expected. Transitioning from child to parent works - i.e. the contents of the template and $state.current change as expected - but the URL does not update in the browser.
To be clear, an example: I'm in /geo/california and I click a button with ui-sref='home'. I've confirmed that the correct href='#/' has been placed on the button, and clicking it causes the $state to transition back to the home state, but /geo/california remains in my address bar.
What am I missing here?
Update in respose to #UlukBiy's comment: No, home does not have a ui-view in its template. The ui-view is in the template of it's parent: The overall structure is:
<body>
<div app-nav></div>
<div ui-view></div>
</body>
So the home directive gets inserted into the ui-view, but it contains no ui-views of its own. Is that my problem? I'm new to UI-router, and assumed there was some low-level misunderstanding about the role of states vs. directives when I posted this. If so, please help me correct it.
This scenario should be working. There is a working example (click the blue button right-top to run example in separate window, showing the address bar)
I updated your state def a bit:
$stateProvider
.state('home', {
url: "/",
template: 'Home view <hr /> Geo view: <div ui-view></div>',
})
.state('home.geo', {
url:'^/geo/{geo}',
templateUrl: 'tpl.html',
})
All these links do work as expected:
<a href="#/home">
<a href="#/geo/california">
<a href="#/geo/czechia">
<a ui-sref="home">
<a ui-sref="home.geo({geo:'california'})">
<a ui-sref="home.geo({geo:'czech'})">
So, the most important change here is that for a child state we should use this url:
url:'^/geo/{geo}',
instead of the url:'/geo/{geo}'. Check the doc:
Absolute Routes (^)
If you want to have absolute url matching, then you need to prefix your url string with a special symbol '^'.
Check the working example here