Передать значение с одного маршрутизатора на другой с помощью Mojolicious::Lite

из формы ajax вызывается имя найденного маршрутизатора, мне нужно обработать значение и передать его другому маршрутизатору, я не могу понять, как это сделать, вот пример того, как я пытаюсь:

#!/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');
   ...
 };

Благодарю вас!


person Maresia    schedule 23.02.2017    source источник
comment
Хотите динамически установить новый маршрут? Ваш код выглядит так. Я думаю, что это маловероятно, и вы, вероятно, захотите просто выполнить внутреннюю переадресацию, по сути, вызвав /process_name. Это правильно?   -  person simbabque    schedule 23.02.2017
comment
Да, у меня есть несколько внутренних маршрутов, которым нужно так общаться.   -  person Maresia    schedule 23.02.2017


Ответы (2)


Вам нужно искать маршруты через ваш объект Mojolicious::Routes внутри вашего app. Имя для 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, вы должны передать его. У вас также есть ключевое слово app, доступное в любом sub, который вы определяете.

person simbabque    schedule 23.02.2017
comment
Мне нравится второй подход, так как я конвертирую приложение из стандартного Perl в стиль фреймворка. Но у меня возникает вопрос, когда нужно преобразовать подпрограмму в Perl в маршрутизатор с использованием Mojolicious:: Lite? - person Maresia; 23.02.2017
comment
@Maresia Я бы преобразовал точки прямого доступа только в маршруты (не маршрутизатор, это то, что обрабатывает входящие запросы). Таким образом, у каждой точки входа есть подпрограмма. Mojo вызывает эти контроллеры (поэтому и есть $c). Обычно вы держите их плоскими. Я бы дошел до того, что создал отдельные пакеты для бизнес-логики и оттуда вызывал функции. Или сделать их объектами. - person simbabque; 23.02.2017
comment
Извините за опечатку в роутере. То, что вы сказали, имеет смысл. Точка входа маршрут, с маршрута звонок на подпрограмму для обработки данных и так далее. Документация повсюду, слишком широкая, не могли бы вы порекомендовать какой-нибудь сайт с дополнительными пояснениями по этой теме? - person Maresia; 23.02.2017
comment
@Maresia Я действительно не использую Mojolicious. Я работаю с Catalyst и Dancer2. Но стратегия везде одинаковая. Прочтите шаблон mvc , особенно то, как он используется для веб-приложений. Если вы держите свою бизнес-логику вне фактического веб-слоя, вы можете легко написать тесты для нее, и она более переносима. - person simbabque; 23.02.2017
comment
Нужно еще немного потренироваться в этом деле, но спасибо за информацию. - person Maresia; 23.02.2017
comment
Могу я задать вам еще один вопрос, связанный с преобразованием стандартного perl . В таблице диспетчеризации, которая вызывает 2 подпрограммы, как бы вы подошли к преобразованию кода в маршруты? my %data = (more_data =› sub { address( addr =› $q-›param('addr'), ), acc( zip =› $q-›param('zip'), ) }, ); мой $процесс = $данные{'more_data'}; $процесс-›(); - person Maresia; 23.02.2017
comment
@Maresia нет стандартного Perl. Все это Perl, просто разные фреймворки. Теперь у вас есть CGI-скрипт, и вы хотите превратить его в MVC-приложение. Подумайте о том, что приложение делало раньше, и насколько точно вы хотите сопоставить это с вашим новым приложением. Каждая точка входа — это один маршрут. Все остальное — бизнес-логика. Если у вас еще нет инкапсулированной бизнес-логики, возможно, будет хорошим началом сделать это сначала в старом коде. Затем вы можете перенести его шаг за шагом. Но это становится очень широким и не подходит к этому вопросу. - person simbabque; 24.02.2017

Для исходного вопроса я бы использовал

$c->redirect_to()

См. этот вопрос для получения подробной информации о передаче переменной: the-target-con">Передача аргументов в redirect_to в mojolicious и их использование в целевом контроллере

======

Но я бы больше занялся написанием сабвуферов (как уже говорили другие). Если у вас есть существующая логика, вы можете обернуть ее в хелпер или просто добавить логику в хелпер и вызвать его.

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);
    }
};
person shaneburgess    schedule 26.02.2017