【问题标题】:Pass value from one router to another using Mojolicious::Lite使用 Mojolicious::Lite 将值从一台路由器传递到另一台路由器
【发布时间】:2017-02-23 15:48:13
【问题描述】:

从一个 ajax 表单中调用了这个路由器 foundname,我需要处理该值并将其传递给另一个路由器,我不知道该怎么做,这是我尝试的示例:

#!/usr/bin/perl

use Mojolicious::Lite;

get '/foundname' => sub {

  my $c = shift;
  # Here I get the value from the form
  my $name_on = $c->req->query_params->param('name');

  if($name_on) {
    # call another router and pass the name value to it
    # It gives an error "Can't locate object method "get" ", I might not need to use "get", just don't know how to pass the value.
    $c->get('/process_name')->to( searched => $name_on);
   }

};

 get '/process_name' => sub {

   my $c = shift;
   my $got_name = $c->req->query_params->param('searched');
   ...
 };

谢谢!

【问题讨论】:

  • 要动态安装新路由吗?您的代码如下所示。我认为这不太可能,您可能只想做一个内部转发,基本上是调用/process_name。对吗?
  • 是的,我有几个内部路由需要像这样进行通信。

标签: perl mojolicious mojolicious-lite


【解决方案1】:

您需要通过 app 内部的 Mojolicious::Routes 对象查找路由。 lookup 的名称由 Mojolicious::Lite 从 URI 的路径部分自动生成,因此 /process_name 的名称为 process_name

你得到一个Mojolicious::Routes::Route,它有一个render方法,你可以在那里传递你的参数。

use Mojolicious::Lite;

get '/foundname' => sub {
    my $c = shift;

    my $name_on = $c->req->query_params->param('name');

    if( $name_on ) {
        my $process_name = app->routes->lookup('process_name')->render( { searched => $name_on } );
        $c->render( text => $process_name );
    }
};

get '/process_name' => sub {
   my $c = shift;
   my $got_name = $c->req->query_params->param('searched');

   $c->render( text => $got_name );
};

app->start;

当你卷曲这个时,你会得到参数作为响应。

$ curl localhost:3000/foundname?name=foo
/process_name

但是,这可能不是正确的方法。如果要实现业务逻辑,则不应为此使用内部或隐藏路由。请记住,您的应用程序仍然只是 Perl。您可以写一个sub 并调用它。

use Mojolicious::Lite;

get '/foundname' => sub {
    my $c = shift;

    my $name_on = $c->req->query_params->param('name');

    if( $name_on ) {
        my $got_name = process_name( $name_on );
        $c->render( text => $got_name );
    }
};

sub process_name {
    my ( $got_name ) = @_;

    # do stuff with $got_name

    return uc $got_name;
};

app->start;

这将输出

$ curl localhost:3000/foundname?name=foo
FOO

这是一种更便携的方法,因为您可以轻松地对这些函数进行单元测试。如果你想拥有$c,你必须传递它。您还可以在您定义的任何 sub 中使用 app 关键字。

【讨论】:

  • 我喜欢第二种方法,因为我正在将应用程序从“标准 perl”转换为框架样式。但这向我提出了一个问题,perl 中的子例程何时需要使用 Mojolicious::Lite 转换为路由器?
  • @Maresia 我只会将直接访问点转换为 routes(不是 router,这是处理传入请求的东西)。所以每个入口点都有一个子。 Mojo 称这些控制器(这就是为什么有$c)。通常你保持这些平坦。我什至会为业务逻辑创建单独的包并从那里调用函数。或者使它们成为对象。
  • 对不起,“路由器”错字。你说的有道理。入口点一个路由,从路由一个调用到一个子来处理数据等等。文档无处不在,您会推荐一些对此主题有更多解释的网站吗?
  • @Maresia 我并没有真正使用 Mojolicious。我与 Catalyst 和 Dancer2 合作。但是策略在任何地方都是一样的。阅读the mvc pattern,尤其是它如何用于 Web 应用程序。如果您将业务逻辑置于实际的 Web 层之外,您可以轻松地为它编写测试,并且它更具可移植性。
  • 需要接受更多关于这件事的培训,但感谢您提供的信息。
【解决方案2】:

对于最初的问题,我会使用

$c->redirect_to()

有关传递变量的详细信息,请参阅此问题: Passing arguments to redirect_to in mojolicious and using them in the target controller

======

但是,我会更多地考虑编写潜艇(正如其他人所说)。 如果你有现有的逻辑,那么你可以将它包装在一个帮助器中,或者只是将逻辑扔到一个帮助器中并调用它。

helper('process_name'=> sub{
    my $self,$args = @_;

    # Do some logic with $args->{'name'}
    return $something;
});

get '/foundname' => sub {
    my $c = shift;

    my $name_on = $c->req->query_params->param('name');

    if( $name_on ) {
        my $process_name = $c->process_name({name => $name_on});
        $c->render( text => $process_name );
    }else{
      $c->redner(text => 'Error',status=>500);
    }
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 2021-03-05
    • 2019-09-22
    • 2020-11-26
    • 2017-03-12
    • 1970-01-01
    • 2018-01-06
    相关资源
    最近更新 更多