Is it possible to setup a route in ui-router
that only has a controller? The purpose being that at a certain URL, the only thing I'd like to do is take action programatically, and not display anything in terms of a view. I've read through the docs, but I'm not sure if they offer a way to do this.
Yes, I have read this: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-open-a-dialogmodal-at-a-certain-state, but that is not quite what I am looking for.
For example, let's just say I have a basic body with view:
<body ui-view></body>
And some basic config:
// Routes
$stateProvider
.state('myaction', {
url: "/go/myaction",
onEnter: function() {
console.log('doing something');
}
});
When /go/myaction
is visited, the view is blank. Is it possible to do this?
I was able to solve this problem by redirecting the headless state I was taking programmatic action in, to a state WITH a view at the end of the headless state:
$stateProvider
.state('myaction', {
url: "/go/myaction",
onEnter: function() {
console.log('doing something');
}
controller: function($state) {
$state.go('home');
}
});
You can't have a controller without a view but you can use onEnter
instead of a controller. If you don't want to change the current view when accessing this state you can define it as a child state:
$stateProvider
// the parent state with a template
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'HomeCtrl'
})
// child of the 'home' state with no view
.state('home.action', {
url: '/action',
onEnter: function() {
alert('Hi');
},
});
Now in home.html
you can do something like this:
<a href ui-sref=".action">Greet me!</a>
From the docs:
Warning: The controller will not be instantiated if template is not defined.
Why don't you use an empty string as a template to overcome this?
Yes, you can do that. Use absolute view names to re-use the <ui-view>
of another state.
Take a look at this example:
Users go to my app, but depending on them being authenticated or not, I want to send them to a public or private page. I use the index
state purely to see if they're logged in or not, and then redirect them to index.private
or index.public
.
The child states make use of absolute view names to use the <ui-view>
element that corresponds to the index
state. This way, I don't need to make a second nested <ui-view>
.
$stateProvider.state('index', {
url: "/",
controller: 'IndexCtrl'
}).state('index.private', {
views: {
"@": {
templateUrl: 'private.html',
controller: 'PrivateCtrl'
}
}
}).state('index.public', {
views: {
"@": {
templateUrl: 'public.html',
controller: 'PublicCtrl'
}
}
});
A small note on this example: I'm using the @
shortcut here. Normally you would use viewname@statename
.
My solution for this was just to include a template (html file) that is blank.