luchao
luchao

Reputation: 13

How should I use requestAction in the view with CakePHP 3.x

My code:

// View/Activities/index.ctp
...
<div>
    <?php echo $this->requestAction('/Activities/ajax_list/'.$categoryId,['return']);?>
</div>
...

//View/Activitest/ajax_list.ctp
....
<?php echo $this -> Html -> image("/img/add1.jpg"); ?>
...
<?php echo $this->Html->link('add_project', array('controller'=>'projects', 'action'=>'add', $categoryId)); ?>
....

I want to include the view 'ajax_list' into the 'index',and it has been displayed but the url of image and link was wrong.

Then I debug the Cake/Routing/RequestActionTrait.php , "requestAction" function I find "$request = new Request($params);" the $request->base , $request->webroot are null.

Could some one tell me how should I fix it?

Upvotes: 0

Views: 4505

Answers (1)

ndm
ndm

Reputation: 60463

The $base/$webroot properties not being set in the new request might be considered a bug, or maybe the docs are just missing a proper example solution, I can't tell for sure, you might want to report this over at GitHub and see what the devs say.

Use view cells instead of requestAction()!

Whenever applicable you're better off using view cells instead of requesting actions, as they avoid all the overhead that comes with dispatching a new request.

See Cookbook > Views > View Cells

No models involved? Use elements!

In case no models are involed, and all you are doing is generating HTML, then you could simply use elements.

See Cookbook > Views > Elements

Fixing requestAction()

A possible workaround would be to use a dispatcher filter that fills the empty $base/$webroot properties with the necessary values, something like

src/Routing/Filter/RequestFilterFix.php

namespace App\Routing\Filter;

use Cake\Event\Event;
use Cake\Routing\DispatcherFilter;

class RequestFixFilter extends DispatcherFilter
{
    public function beforeDispatch(Event $event)
    {
        $request = $event->data['request'];
        /* @var $request \Cake\Network\Request */

        if ($request->param('requested')) {
            $request->base = '/pro';
            $request->webroot = '/pro/';
            $request->here = $request->base . $request->here;
        }
    }
}

config/bootstrap.php

// ...

// Load the filter before any other filters.
// Must at least be loaded before the `Routing` filter.
DispatcherFactory::add('RequestFix');

DispatcherFactory::add('Asset');
DispatcherFactory::add('Routing');
DispatcherFactory::add('ControllerFactory');
// ...

See also Cookbook > Routing > Dispatcher Filters > Building a Filter

Upvotes: 4

Related Questions