How to inject services into RouteInitializerFn (ne

2019-02-17 00:50发布

问题:

I'm switching my app over to the new routing DSL. Specifically, I want to do something like this with preEnter:

final RouteInitializerFn routes =(Router router, ViewFactory views) {
  views.configure({
   'chat': ngRoute(
     path: '/chat',
     // authService.requireState returns a Future<bool>, and may invoke an HttpRequest
     preEnter: (RoutePreEnterEvent e) => e.allowEnter(authService.requireState(LOGGED_IN)),
     view: 'views/chat.html'),

   'login': ngRoute(
     path: '',
     defaultRoute: true,
     view: 'views/login.html')
  });
}

This would be configured in the module as follows:

value(RouteInitializerFn, routes);

In case you missed it, I'm referencing an injectable authService within the RouteInitializerFn. This isn't possible since RouteInitializerFn is a function and not a class, so nothing can be injected into it. If I encapsulated the routes function within a class, I'm not sure how I could configure RouteInitializerFn, so I'm in a bit of a quandary.

回答1:

I found a pretty cool solution to this problem. Turns out, if you define a call method on a class that satisfies a typedef, you can configure it as an implementation of the typedef. Very cool. Here is my solution:

class Routes
{
  final UserService _userService;

  Routes(this._userService);

  void call(Router router, ViewFactory views) 
  {
    views.configure({
      'chat': ngRoute(
          path: '/chat',
          preEnter: (RoutePreEnterEvent e) => e.allowEnter(this._userService.requireUserState(UserService.LOGGED_IN)),
          view: 'views/chat.html'
      ),

      'login': ngRoute(
          path: '',
          defaultRoute: true,
          view: 'views/login.html'
      )
    });
  }
}

and this is how it's configured within the module:

// old syntax
type(RouteInitializerFn, implementedBy: Routes);

// new syntax
bind(RouteInitializerFn, toImplementation: Routes);