ui-router: A route with no view template

2020-05-30 02:25发布

问题:

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?

回答1:

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');
    }
  });


回答2:

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>


回答3:

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?



回答4:

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.



回答5:

My solution for this was just to include a template (html file) that is blank.