Set default child of abstract nested state in ui-router - javascript

I use ui-router.
Here are my nested states:
$stateProvider
.state('books', {
abstract: true,
url: '/books',
controller: 'BooksCtrl',
templateUrl: 'contents/books.html'
})
.state('books.top', {
url: '/top',
templateUrl: 'contents/books-top.html'
})
.state('books.new', {
url: '/new',
templateUrl: 'contents/books-new.html'
});
How can I set books.new state to be default child of the books abstract state, so then when you hit /books ui-router redirects to /books/new?

There is a working example
We can use built in features. 1) default is such child state which has empty url:
$stateProvider
.state('books', {
abstract: true,
url: '/books/new',
controller: 'BooksCtrl',
..
})
.state('books.new', {
//url: '/new',
url: '',
...
})
.state('books.top', {
url: '^/books/top',
...
});
And 2) to keep /books in place, we can use redirection
$urlRouterProvider.when('/books', '/books/new');
And these links will work as expected:
// href
<a href="#/books">
<a href="#/books/new">
<a href="#/books/top">
//ui-sref
<a ui-sref="books.top">
<a ui-sref="books.new">
Check it here

Try this way:
$stateProvider
.state('books', {
abstract: true,
url: '/books',
controller: 'BooksCtrl',
templateUrl: 'contents/books.html'
})
.state('books.top', {
url: '/top',
templateUrl: 'contents/books-top.html'
})
.state('books.new', {
url: '',
templateUrl: 'contents/books-new.html'
});
EDIT: I know that's not very nice, but you can create additional state with same arguments except url:
var booksArgs = {
url: '',
templateUrl: 'contents/books-new.html'
};
$stateProvider.state('books.new', booksArgs);
$stateProvider.state('books.new_', angular.extend({}, booksArgs, {
url: '/new'
}));
Another solution from this post:
In states configuration:
$stateProvider
.state('books', {
url: '/books',
controller: 'BooksCtrl',
templateUrl: 'contents/books.html',
redirectTo: '.new'
})
.state('books.top', {
url: '/top',
templateUrl: 'contents/books-top.html'
})
.state('books.new', {
url: '/new',
templateUrl: 'contents/books-new.html'
});
On module run:
app.run(['$rootScope', '$state', function($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(evt, to, params) {
if (to.redirectTo) {
evt.preventDefault();
$state.go(to.redirectTo, params, { relative: to });
}
});
}]);

Related

ionic 1 - How to enable back button on header - angularjs

When I navigating from home page to another, back button not displaying at the navigation bar. However, there are certain case where ionic display the back button. e.g navigate Settings page form profile page back button display properly and mobile bank button also working fine.
The Goal is user have to go to home page when press mobile hardware back button with display back button on navigation bar and on home page display confirmation when press hardware back button.
I have already searched lots of Q&A over stack but nothing found proper solutions for this.
Here is my code that try to -
.run(function($ionicPlatform, $rootScope, $ionicLoading, $ionicPopup, $ionicHistory, $localStorage, $timeout, $http, $state) {
$ionicPlatform.ready(function() {
$ionicPlatform.registerBackButtonAction(function(event) {
if ($state.current.name=="app.home") {
$ionicPopup.confirm({
title: 'System',
template: 'are you sure you want to exit?'
}).then(function(res) {
if (res) {
ionic.Platform.exitApp();
}
})
}
}, 101);
});
})
How can I force Ionic to display back button on certain page?
.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.home', {
url: '/home',
views: {
'menuContent': {
templateUrl: 'templates/home.html',
controller: 'HomeCtrl'
}
}
})
.state('app.settings', {
cache:false,
url: '/settings',
views: {
'menuContent': {
templateUrl: 'templates/setting/settings.html',
controller: 'SettingsCtrl'
}
}
})
.state('app.wfhadd', {
cache:false,
url: '/wfh/wfhadd',
views: {
'menuContent': {
templateUrl: 'templates/wfh/addwfh.html',
controller: 'AddWfhCtrl'
}
}
})
.state('app.wfhlist', {
cache:false,
url: '/wfh/wfhlist',
views: {
'menuContent': {
templateUrl: 'templates/wfh/wfhlist.html',
controller: 'listWfhCtrl'
}
}
})
.state('app.login', {
cache: false,
url: '/login/:userid/:logpass',
views: {
'menuContent': {
templateUrl: 'templates/login.html',
controller: 'LoginCtrl',
params: {'userid': null, 'logpass': null}
}
}
})
.state('app.profile', {
cache: false,
url: '/settings/profile',
views: {
'menuContent': {
templateUrl: 'templates/setting/profile.html',
controller: 'ProfileCtrl'
}
}
})
.state('app.activities', {
cache: false,
url: '/activities',
views: {
'menuContent': {
templateUrl: 'templates/activities.html',
controller: 'ProfileCtrl'
}
}
})
.state('app.leave', {
cache: false,
url: '/leave',
views: {
'menuContent': {
templateUrl: 'templates/leave/leave.html',
}
}
})
.state('app.leavelist', {
cache: false,
url: '/leave/allleaves/:id',
views: {
'menuContent': {
templateUrl: 'templates/leave/leavelist.html',
controller: 'LeaveCtrl',
params: {'leaveid': null}
}
}
})
.state('app.leavedtls', {
cache: false,
url: '/leave/details',
views: {
'menuContent': {
templateUrl: 'templates/leave/leavedtls.html',
controller: 'LeaveDtlsCtrl'
}
}
})
.state('app.leaveapply', {
cache: false,
url: '/leave/apply',
views: {
'menuContent': {
templateUrl: 'templates/leave/leaveapply.html',
controller: 'LeaveApplyCtrl'
}
}
})
.state('app.terms', {
url: '/settings/terms',
views: {
'menuContent': {
templateUrl: 'templates/policy.html'
}
}
})
.state('app.about', {
url: '/settings/about',
views: {
'menuContent': {
templateUrl: 'templates/about.html'
}
}
})
;
$urlRouterProvider.otherwise('/app/home');
})
EDIT 1
Now I have put following code on profile controller and back button show on Profile page but It's not working (not go back to home page).
.controller('ProfileCtrl', function($scope,$rootScope, $ionicHistory, $http,$localStorage, $ionicNavBarDelegate){
$scope.$on('$ionicView.beforeEnter', function (event, viewData) {
viewData.enableBack = true;
});
})

Multiple abstract views - Ionic

I am building a project with ionic where there are different views handled by ui-router, that needs be nested together. This is the part of the code where the states of the ui-view are handled:
$stateProvider
// setup an abstract state for the tabs directive
.state('filters', {
url: '/filters',
abstract: true,
templateUrl: 'templates/filters.html'
})
// and one for the search bar
.state('search', {
url: '/search',
abstract: true,
templateUrl: 'templates/search.html'
})
// Each tab has its own nav history stack:
.state('filters.search.locations', {
url: '/locations',
views: {
'tab-locations': {
templateUrl: 'templates/tab-locations.html',
controller: 'LocationsCtrl'
}
}
})
.state('filters.search.job-categories', {
url: '/job-categories',
views: {
'tab-job-categories': {
templateUrl: 'templates/tab-job-categories.html',
controller: 'JobCategoriesCtrl'
}
}
})
.state('filters.search.levels', {
url: '/levels',
views: {
'tab-levels': {
templateUrl: 'templates/tab-levels.html',
controller: 'LevelsCtrl'
}
}
});
As you can see, my intention is to combine the states filters & search and display them together, but apparently I am doing something wrong. Do you know what is the issue with my code?
Thanks in advance for your replies!!
Check this out:
$stateProvider
.state('filters', {
url: '/filters',
abstract: true,
templateUrl: 'templates/filters.html'
})
// note this ...
.state('filters.search', {
url: '/search',
abstract: true,
templateUrl: 'templates/search.html'
})
.state('filters.search.locations', {
url: '/locations',
views: {
'tab-locations': {
templateUrl: 'templates/tab-locations.html',
controller: 'LocationsCtrl'
}
}
})
//and so on ...

angular-ui-routing doesn't change the view

I have a problem with ionic and ui-routing, when I go in a child state the url is updated but the view remains the same.
this is my routing.js
.config(function($stateProvider, $urlRouterProvider, $locationProvider, $ionicConfigProvider) {
$ionicConfigProvider.views.maxCache(0);
$stateProvider
.state('app', {
url: "/",
abstract: true,
templateUrl: "menu.html",
controller: "menuCtrl"
})
.state('app.home', {
url: "home",
cache: false,
views: {
'menuContent': {
templateUrl: "home.html",
controller: "homeCtrl"
}
}
})
.state('app.search', {
url: "search",
views: {
'menuContent': {
templateUrl: "search.html",
controller: "searchCtrl"
}
}
})
.state('app.search.product', {
url: "/product/:id",
views: {
'menuContent': {
templateUrl: "productPage.html",
controller: "singleProductCtrl"
}
}
})
.state('app.search.product.market', {
url: "/product/:id",
views: {
'menuContent': {
templateUrl: "market.html",,
controller: "marketCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/home');
});
in this example when I try to go in app.search.product the view doesn't change, even if I go there directly inserting the right url in the browser. I've also tryed with ui-sref-opts="{reload: true} option but nothing change.
Here's a plunker that shows the problem (after search the view doesn't change) https://plnkr.co/edit/JrNFkV50klZItOQS18Iu
I don't have experience with Ionic, but based on the ui-router config angular expects a nested view, but your page has only single view. Meaning, the second level (product) has no view to load into. Since Ionic I suppose doesn't allow nested ionic views (would be funny if it did) you can use normal ui-view as nested one.
<ion-view view-title="Search">
<ion-content>
<h1>Search</h1>
<a ui-sref=".product({id: 1})">Go to product</a>
<ui-view name="secondLevel"></ui-view>
</ion-content>
Check your code with modifications here: https://plnkr.co/edit/LdgmoAEo1pS9spi1Su1z.
Not sure if this is what you were looking for. Based on your plunkr it looks like you've defined nested view accidentally. In which case solution would be to remove .search from *.product state names: https://plnkr.co/edit/PGICsBhzyCOTSe9af4yu
.state('app.product', {
url: "/product/:id",
views: {
'menuContent': {
templateUrl: "productPage.html"
}
}
})
.state('app.market', {
url: "/product/:id",
views: {
'menuContent': {
templateUrl: "market.html"
}
}
});
Use this configuration:
$stateProvider
.state('app', {
url: "/",
abstract: true,
templateUrl: "menu.html",
})
.state('app.home', {
url: "home",
views: {
'menuContent': {
templateUrl: "home.html"
}
}
})
.state('app.search', {
url: "search",
views: {
'menuContent': {
templateUrl: "search.html"
}
}
})
.state('app.product', {
url: "/product/:id",
views: {
'menuContent': {
templateUrl: "productPage.html"
}
}
})
.state('app.market', {
url: "/product/:id",
views: {
'menuContent': {
templateUrl: "market.html"
}
}
});
When you declare 'app.search.product' by example, this means that in the template of the search state (search.html) should be have a view for load the children state, and this it's not the case, your views has been moving in the same "level"
try to put in ui-sref name of the product state in Go To product link tag.
that is ui-sref="app.product"

async factory in ionic sidemenu

I am using ionic framework for my mobile application
what I need is when I click the side menu links I want the factory service to bring data from the server
what is happening now is only one http request sent to the server when the application run ,but when I click on any link in the side menu no requests sent
myapp.factory('Authy',function ($cookieStore,Auth,$http,$q) {
return {
can_go :function(){
var deffered = $q.defer();
$http.get(mainUrl+"/user_info.json")
.success(function(data){
deffered.resolve(data);
}).error(function(){
deffered.reject();
});
return deffered.promise;
}
}
});
in my controller
myapp.controller("PowerCtrl",function($scope,Authy ,$cookieStore,$http ){
$scope.view_loading = true;
Authy.can_go().then(function(data){
$scope.view_loading = false;
if (data.user){
var user = data.user;
if ((user.country !="") && (user.city != "")) {
$scope.coins = user.coins
$scope.id =user.id
$scope.current_vip =user.current_vip;
$scope.vip_time =user.vip_time;
}else{
window.location.href="#/step2";
}
}else{
window.location.href="#/login";
}
});
});
my routers
myapp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state("main",{
url: "/",
templateUrl: "templates/main.html",
controller: "MainCtrl"
})
.state("login",{
url: "/login",
templateUrl: "templates/login.html",
controller: "LoginCtrl"
})
.state("register",{
url: "/register",
templateUrl: "templates/register.html",
controller: "RegisterCtrl"
})
.state("step2",{
url: "/step2",
templateUrl: "templates/step2.html",
controller: "StepCtrl"
})
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.home', {
url: "/home",
views: {
'menuContent': {
controller: "HomeCtrl",
templateUrl: "templates/home.html"
}
}
})
.state('app.power', {
url: "/power",
views: {
'menuContent': {
controller : "PowerCtrl",
templateUrl: "templates/power.html"
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/');
});
You have to disable caching on the view, its enabled by default , Ex:
<ion-view cache-view="false" view-title="My Title!">
...
</ion-view>
read more about caching here

angular-ui-router nested views the page doesn't loading when direct url is used or refresh

I have this plunker which works fine it's better seeing here but there's one bug in there, when navigating to nested state through a clickable link I get the desired behavior, but when refreshing the page or writing the URL and pressing enter the page the page doesn't load for some states.
I have the 4 States:
profile.about
profile.feed
profile.user.about
profile.user.feed
For the first 2 refreshing the page or selecting the URL and pressing enter will load the profile view but not the about view, the second 2 works fine.
the router configuration is like this:
$urlRouterProvider.otherwise("/home");
// route 1
$stateProvider.state('home' , {
url: "/home",
templateUrl: "home.html"
});
// route 2
$stateProvider.state('profile' , {
controllerAs: "Profile",
url: "/profile",
templateUrl: "profile.html",
controller: "ProfileController"
});
// user route
$stateProvider.state('profile.user' , {
controllerAs: "Profile",
url: "^/:username",
controller: "ProfileController",
template: "<div ui-view></div>",
resolve: {
username: ['$stateParams', function ($stateParams) {
return $stateParams.username;
}]
}
});
// route 3
$stateProvider.state('settings' , {
url: "/settings",
templateUrl: "settings.html"
});
// user about route
$stateProvider.state('profile.about', {
controllerAs: "About",
url: "^/about",
templateUrl: "about.html",
controller: "AboutController2"
});
// user about route
$stateProvider.state('profile.user.about', {
controllerAs: "About",
url: "/about",
templateUrl: "about.html",
controller: "AboutController"
});
// user about route
$stateProvider.state('profile.user.feed', {
controllerAs: "Feed",
url: "/feed",
templateUrl: "feed.html",
controller: "AboutController"
});
$stateProvider.state('profile.feed', {
controllerAs: "Feed",
url: "^/feed",
templateUrl: "feed.html",
controller: "AboutController2"
});
I'm not in html5mode as seeing in the plunker and I sow this SO but no answer there.
Any help on how to fix this, thanks in advance.
The problem that I found seconds after posting the question is that the route definitions are not ordered correctly.
the state profile.user have a dynamic url parameter so defining the profile.feed or profile.about after the profile.user will result to this error, therefore defining the profile.about and profile.feed hould be before the profile.user like this:
$urlRouterProvider.otherwise("/home");
// route 1
$stateProvider.state('home' , {
url: "/home",
templateUrl: "home.html"
});
// route 2
$stateProvider.state('profile' , {
controllerAs: "Profile",
url: "/profile",
templateUrl: "profile.html",
controller: "ProfileController"
});
// route 3
$stateProvider.state('settings' , {
url: "/settings",
templateUrl: "settings.html"
});
// user about route
$stateProvider.state('profile.about', {
controllerAs: "About",
url: "^/about",
templateUrl: "about.html",
controller: "AboutController2"
});
$stateProvider.state('profile.feed', {
controllerAs: "Feed",
url: "^/feed",
templateUrl: "feed.html",
controller: "AboutController2"
});
// user route
$stateProvider.state('profile.user' , {
controllerAs: "Profile",
url: "^/:username",
controller: "ProfileController",
template: "<div ui-view></div>",
resolve: {
username: ['$stateParams', function ($stateParams) {
return $stateParams.username;
}]
}
});
// user about route
$stateProvider.state('profile.user.about', {
controllerAs: "About",
url: "/about",
templateUrl: "about.html",
controller: "AboutController"
});
// user about route
$stateProvider.state('profile.user.feed', {
controllerAs: "Feed",
url: "/feed",
templateUrl: "feed.html",
controller: "AboutController"
});
Hope this help someone else to not waste time on such a simple error.

Categories

Resources