I am using ui-router-extras to support parallel state for modal windows. When an modal window is open, the "home" state become inactive, but is still visible in the background. This allows me to have deep link for each modal windows.
However, I am having trouble figure out a good way to set the "default" inactive state to "home" if an user come through a modal window link.
I currently define my states like this:
$stateProvider
.state('signup', {
url: '/signup',
onEnter: function($modal) {
$modal.open({
templateUrl: 'singup.html',
size: 'large',
controller: 'SignUpController'
});
}
})
You only posted one state definition!
I tried to get the same working and finally figured it out. If you found a solution could you post it? If not please provide more details
Maybe my solution will help
angular.module('xbmcremoteApp')
.config(function ($stateProvider,$stickyStateProvider) {
$stickyStateProvider.enableDebug(true);
$stateProvider
.state('movies', {
abstract: true,
url: '/movies',
templateUrl: 'app/movies/movies.html',
controller: 'MoviesCtrl'
}).state('movies.gallery', {
url: '',
templateUrl: 'app/movies/movies-gallery/movies-gallery.html',
controller: 'MoviesGalleryCtrl',
sticky:true
}).state('movies.gallery.details', {
url: '/:id',
onEnter: ['$stateParams', '$state', '$modal', '$resource', function ($stateParams, $previousState, $modal, $resource) {
$modal.open({
templateUrl: 'app/movies/movies-gallery/myModalContent.html',
resolve: {
id: function () {
$stateParams.id
}
},
size:'lg',
controller: 'ModalInstanceCtrl'
}).result.then(function () {
return $previousState.go("movies.gallery");
});
}]
});
});
check out ui-router-extras release 0.0.12 and above. I've added support for default substates in DSR. See this github issue for details:
https://github.com/christopherthielen/ui-router-extras/issues/150
And read the updated API docs here: http://christopherthielen.github.io/ui-router-extras/#/dsr
var myState = {
name: 'foo',
url: '/foo/:fooID/:barID',
template: '<div></div>,
controller: 'fooCtrl',
deepStateRedirect: {
default: { state: "foo.bar.baz.defaultSubState", params: { defaultStateParam1: "99" } }
}
}
Related
Hi I have been using stateprovider for a long time and this time I want to implement a functionality in which without changing the url, I want to go not found state but not on url.
This is my code.
(function () {
angular.module('mean').config(aosOfferConfig);
function aosOfferConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/link/404_not_found");
$stateProvider
.state('offers', {
url: '/offers/packages',
templateUrl: 'views/aosOffers/aosoffers.html',
controller: 'offersController',
controllerAs: 'packages'
})
.state('offersignup', {
url: '/offers/signup',
templateUrl: 'views/aosOffers/offerssignup.html',
controller: 'offersSignupController',
controllerAs: 'offerssignup'
})
.state('thankyou', {
url: '/offers/thankyou',
templateUrl: 'views/aosOffers/offersthankyou.html'
});
}
})();
Now in my otherwise part I am taking the user to /link/404_not_found. I don't want this. Instead, I want that it will remain in current url but the state should be changed. Just like github does.
How can I do this ?
do it this way
(function () {
angular.module('mean').config(aosOfferConfig);
function aosOfferConfig($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise(function ($injector, $location) {
var state = $injector.get('$state');
state.go('404_not_found', {}, { location: false });
return $location.path();
});
$stateProvider
.state('offers', {
url: '/offers/packages',
templateUrl: 'views/aosOffers/aosoffers.html',
controller: 'offersController',
controllerAs: 'packages'
})
.state('offersignup', {
url: '/offers/signup',
templateUrl: 'views/aosOffers/offerssignup.html',
controller: 'offersSignupController',
controllerAs: 'offerssignup'
})
.state('thankyou', {
url: '/offers/thankyou',
templateUrl: 'views/aosOffers/offersthankyou.html'
})
.state('404_not_found', {
template: '<h1>Notfound</h1>'
});
}
})();
I'm trying to create a nested state config. When I go with the simple non-nested it works, but when I attempt to do it in a nested fashion it fails.
Below is the working code: (Notice the last state 'new')
app.config(
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/views/home.html',
controller: 'MainCtrl',
resolve: {
qstnrPromise: ['qstnrs', function(qstnrs) {
return qstnrs.getAll();
}]
}
})
.state('questionnaires', {
url: '/questionnaires/{id}',
templateUrl: '/views/questionnaire.html',
controller: 'QuestionsCtrl',
resolve: {
questionnaire: ['$stateParams', 'qstnrs', function($stateParams, qstnrs){
return qstnrs.get($stateParams.id);
}]
}
})
.state('new', {
url: '/questionnaires/{id}/new',
template: '<h3> testy </h3>'
});
//$urlRouterProvider.otherwise('home');
$urlRouterProvider.otherwise(function($injector, $location){
$injector.invoke(['$state', function($state) {
$state.go('home');
}]);
});
});
If I attempt to change it with the following, it fails. The URL on browser changes but I don't receive the template.
.state('questionnaires.new', {
url: '/new',
template: '<h3>New question</h3>'
});
Have I understood states incorrectly? Or where have I gone wrong?
Try changing your new state to:
.state('new', {
url: '/new',
parent: 'questionnaires',
template: '<h3>New question</h3>'
})
See if that works for you.
You can make the questionnaires state abstract.
$stateProvider
.state('questionnaires', {
abstract: true,
url: '/questionnaires',
})
.state('questionnaires.new', {
// url will become '/questionnaires/new'
url: '/new'
//...more
})
But in this case you will need to add one additional nested state in order to implement the functionality you need for the $stateParams.id.
I an trying to develop an angular app using ui router, however I am stuck trying to get the controllerAs syntax working correctly.
my stateProvider looks like this
$stateProvider
.state('microsite', {
url: "/",
templateUrl: "microsite.tmpl.html",
abstract: true
})
.state('microsite.home', {
url: "",
templateUrl: "home.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'Introduction'
}
})
.state('microsite.features', {
url: "/features",
templateUrl: "features.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'Features'
}
})
.state('microsite.about', {
url: "/about",
templateUrl: "about.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'About'
}
});
As you can see I setup an abstract default view, and three pages.
I have also assigned a data object with a page_name for each page. This feeds into my controller
myapp.controller('MicrositeController', ['$state', function($state) {
var vm = this;
vm.page_name = $state.current.data.page_name;
vm.sidenav_locked_open = false;
vm.toggleSideNav = function() {
if ($mdMedia('gt-sm')) {
vm.sidenav_locked_open = !vm.sidenav_locked_open;
} else {
$mdSidenav('left').toggle();
}
}
}]);
and then delivers the name to the page via the vm.page_name variable.
However this is not happening. The variable never makes it to the page.
Also I have a vm.toggleSideNav function that is suppose to open and close the sidenav, but that never gets called.
the toolbar with the sidenav button is this
<md-toolbar layout="row" class="md-whiteframe-glow-z1 site-content-toolbar">
<div class="md-toolbar-tools docs-toolbar-tools" tabIndex="-1">
<md-button class="md-icon-button" ng-click="vm.toggleSideNav()" aria-label="Toggle Menu">
XXX
</md-button>
<h1>{{vm.page_name}}</h1>
</div>
</md-toolbar>
here is a plnkr example http://plnkr.co/edit/Na5zkF?p=preview
I am looking for someone to help me figure out the last piece on how to get the toggleSideNav function to get called when I click on the xxx button, and how to get the title to display in the toolbar.
From the Docs:
controller
(optional)
string
function
Controller fn that should be associated with newly related scope or the name of a registered controller if passed as a string. Optionally, the ControllerAs may be declared here.
controller: "MyRegisteredController"
controller:
"MyRegisteredController as fooCtrl"
controller: function($scope, MyService) {
$scope.data = MyService.getData(); }
— UI Router $stateProvider API Reference.
According to the Docs, your controller declaration is correct.
controller: 'MicrositeController as vm'
You need to look for your problem elsewhere.
UPDATE
Put the controller in the root state:
$stateProvider
.state('microsite', {
url: "/",
templateUrl: "microsite.tmpl.html",
//IMPORTANT == Put controller on root state
controller: 'MicrositeController as vm',
abstract: true
})
.state('microsite.home', {
url: "",
templateUrl: "home.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'Introduction'
}
})
.state('microsite.features', {
url: "/features",
templateUrl: "features.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'Features'
}
})
.state('microsite.about', {
url: "/about",
templateUrl: "about.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'About'
}
});
})
The DEMO on PLNKR
Try adding the option controllerAs: 'vm' to the state params instead defining the controller as in the controller option.
Try adding the option controllerAs: 'vm' to the state params instead defining the controller as in the controller option.
or, if I'm not mistaken, you can add
myapp.controller('MicrositeController as vm' ...
Forgive me but I have spent the last 3 hours or so trying to work around this issue. I have settled for not passing params and simply just swiping to a new state without passing params just for the sake of getting it done but No Luck!
THE ERROR.
Error: Could not resolve 'app.current-trip.html' from state 'app.today'
at Object.transitionTo
The trip-details.html modal where the on-swipe functions is located...
<button on-swipe-right="onSwipeRight()"class="button">SLIDE RIGHT to Start Trip</button>
The BookingsController.js - where the app function's logic is located.
angular.module('starter')
.controller("BookingsCtrl", function($scope, $stateParams, $state, $ionicModal, BookingsService, driverLocationService) {
$scope.onSwipeRight = function() {
$state.go('app.current-trip.html');
}
The state routing in app.js..
.state('app.today', {
url: '/today/:user_id/:driver_id',
views: {
'menuContent': {
templateUrl: 'templates/today.html',
controller: 'BookingsCtrl'
}
}
})
.state('app.trip-details', {
url: '/trip-details',
views: {
'menuContent': {
templateUrl: 'templates/trip-details.html',
controller: 'BookingsCtrl'
}
}
})
.state('app.current-trip', {
url: '/current-trip',
views: {
'menuContent': {
templateUrl: 'templates/current-trip.html',
controller: 'BookingsCtrl'
}
}
})
Does it matter that the current-trip.html is a modal? and not an actual view?
Use the state name, not the template filename. Try:
$state.go('app.current-trip');
I have a job state with :jobId parameter.
$stateProvider
.state('employer', {
url: "/",
abstract: true,
templateUrl: '../partials/employer/employerHome.html',
controller: 'UserHomeController',
})
.state('employer.edit', {
url: "^/edit",
templateUrl: '../partials/employer/profile.html',
controller: 'UserHomeController',
})
.state('employer.jobs', {
url: "^/jobs",
templateUrl: '../partials/employer/jobs.html',
controller: 'formController'
})
.state('job', {
parent: 'employer.jobs',
url: '/job/:jobId',
// abstract: true,
controller: 'formController',
onEnter: ['$uibModal', '$state', '$http', '$stateParams', function ($uibModal, $state, $http, $stateParams) {
console.log('Open modal');
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
backdrop: false,
windowClass: 'right fade',
keyboard: true,
controller: 'PostModalInstanceCtrl',
resolve: {
job: function () {
return $stateParams.jobId;
},
},
}).result.finally(function () {
$state.go('employer.jobs');
console.log('job modal closed')
});
}],
})
.state('system_matches', {
parent: 'job',
url: "/system_matches",
controller: 'TController',
views: {
'job#': {
templateUrl: '../partials/employer/system_matches.html',
}
}
});
when I go to the system_matches state the URL looks good: /employer#/jobs/job/1/system_matches and the HTML is loading in the console but cant see the view.
the job/:jobId state is in a modal and from there I want to go to
the system matches state that is not in a modal.
I guess I need to add a ui-view div. my question is where do I need to put the div and how is it supposed to be named with the id parameter?