将重新路由委托给控制器
Delegate Rerouting to Controller
Mojolicious + 催眠蟾蜍。
我希望我的控制器重新路由请求的剩余部分,这样我就不必在主脚本级别声明所有路由。
因此,例如,'/foo/bar/baz' 应该路由到 Controller 'FOO',然后它将决定 'bar/baz' 的路由,在其内部。
主脚本:
package MyApp;
use Mojo::Base 'Mojolicious';
use Mojolicious::Plugin::Config;
sub startup {
my $self = shift;
$self->moniker('MyApp');
$self->plugin('Config');
my $r = $self->routes;
$r->any('/foo/*remainder')->to('FOO#rerouter')->name('TEST_NAME');
}
我试过一种方法,通过动态添加路由,但是 运行 它多次显示不一致 - 可能是由竞争条件或其他原因引起的:
package MyApp::Controller::FOO;
use Mojo::Base 'Mojolicious::Controller';
sub rerouter {
my $self = shift;
my $r = Mojolicious::Routes->new;
$r->get('bar/:baz')->to('myInternalControllerAction');
my $current_route = $self->current_route; # 'TEST_NAME'
$self->app->routes->find($current_route)->add_child($r);
}
sub myInternalControllerAction { #stuff }
这似乎与另一个答案一致:
"The router is dynamic until the first request has been served, after
that, the router cannot change routes"
即使这确实有效,执行也会退出控制器 FOO,然后通过动态添加的路由以不同的操作重新进入它。
我能做到的另一种方法是在控制器的 "re-router" 中创建一个分派 table,因为无论如何我都可以访问请求的其余部分:
sub rerouter {
my $self = shift;
my $remainder = $self->stash->{remainder};
# ...
}
但后来我失去了 Mojolicious 调度程序的好处 - 我将不得不自己解析剩余的请求 URL / 路径。感觉很脏。
钩子在这里似乎也不合适。
我怎样才能优雅地让控制器路由它自己的子部分?
我按如下方式解决了这个问题:
use MyApp::Controller::FOO;
my $r = $self->routes;
my $r_root = $r->under('/' => sub { return 1; });
my $baz = $r_root->under('/baz' => sub { return 1; });
$baz->add_child($MyApp::Controller::FOO::routes);
然后在模块中:
package MyApp::Controller::FOO;
use Mojo::Base 'Mojolicious::Controller';
our $routes = Mojolicious::Routes->new;
my $r = $routes->under('/')->to('FOO#bar');
sub bar { ... }
可能没有那么优雅,但对我来说效果很好。
Mojolicious + 催眠蟾蜍。
我希望我的控制器重新路由请求的剩余部分,这样我就不必在主脚本级别声明所有路由。
因此,例如,'/foo/bar/baz' 应该路由到 Controller 'FOO',然后它将决定 'bar/baz' 的路由,在其内部。
主脚本:
package MyApp;
use Mojo::Base 'Mojolicious';
use Mojolicious::Plugin::Config;
sub startup {
my $self = shift;
$self->moniker('MyApp');
$self->plugin('Config');
my $r = $self->routes;
$r->any('/foo/*remainder')->to('FOO#rerouter')->name('TEST_NAME');
}
我试过一种方法,通过动态添加路由,但是 运行 它多次显示不一致 - 可能是由竞争条件或其他原因引起的:
package MyApp::Controller::FOO;
use Mojo::Base 'Mojolicious::Controller';
sub rerouter {
my $self = shift;
my $r = Mojolicious::Routes->new;
$r->get('bar/:baz')->to('myInternalControllerAction');
my $current_route = $self->current_route; # 'TEST_NAME'
$self->app->routes->find($current_route)->add_child($r);
}
sub myInternalControllerAction { #stuff }
这似乎与另一个答案一致:
"The router is dynamic until the first request has been served, after that, the router cannot change routes"
即使这确实有效,执行也会退出控制器 FOO,然后通过动态添加的路由以不同的操作重新进入它。
我能做到的另一种方法是在控制器的 "re-router" 中创建一个分派 table,因为无论如何我都可以访问请求的其余部分:
sub rerouter {
my $self = shift;
my $remainder = $self->stash->{remainder};
# ...
}
但后来我失去了 Mojolicious 调度程序的好处 - 我将不得不自己解析剩余的请求 URL / 路径。感觉很脏。 钩子在这里似乎也不合适。
我怎样才能优雅地让控制器路由它自己的子部分?
我按如下方式解决了这个问题:
use MyApp::Controller::FOO;
my $r = $self->routes;
my $r_root = $r->under('/' => sub { return 1; });
my $baz = $r_root->under('/baz' => sub { return 1; });
$baz->add_child($MyApp::Controller::FOO::routes);
然后在模块中:
package MyApp::Controller::FOO;
use Mojo::Base 'Mojolicious::Controller';
our $routes = Mojolicious::Routes->new;
my $r = $routes->under('/')->to('FOO#bar');
sub bar { ... }
可能没有那么优雅,但对我来说效果很好。