Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ui-router: A route with no view template

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?

like image 459
vcardillo Avatar asked Oct 04 '13 01:10

vcardillo


4 Answers

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');
    }
  });
like image 75
vcardillo Avatar answered Nov 14 '22 20:11

vcardillo


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>
like image 38
Petr Peller Avatar answered Nov 14 '22 21:11

Petr Peller


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?

like image 1
package Avatar answered Nov 14 '22 21:11

package


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.

like image 1
JacobF Avatar answered Nov 14 '22 20:11

JacobF