Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a controller from within a view - Laravel

Tags:

laravel

I have a view that lists timesheets.

on that view, each timesheet has a deliverable field... I have a DeliverableController that has an action "DropdownList" that calls upon the model and gets a list of deliverables and pushes them to a deliverable view (which just creates a dropdown box).

When im looping through my timesheets I would like to get the response of the DeliverableController/DropdownList and put it where my deliverable field should be on the timesheet.

  • A) is there a way of getting the response of a controller from within a view
  • B) is there a way of getting the response of a controller from within a controller method, so that I can push the result to the view?

My code so far is:

DeliverableController:

class DeliverableController extends BaseController {   
    private $deliverableRepository;

    function __Construct( IDeliverableRepository $deliverableRepo )
    {
        $this->deliverableRepository = $deliverableRepo;
    }

    ...

    public /*  */ function DropdownList()
    {        
        $deliverables = $this->deliverableRepository->Deliverables(); 
        return View::make( 'Deliverable/_DropdownList', array( "Model" => $deliverables ) );
    }
}

Deliverables/_DropdownList View:

<?php
    foreach( $Model as $item )
    {
?>
    <select name="">
        <option value = "<?php echo $item->ID; ?>"><?php echo $item->Title; ?></option>
    </select>    
<?php
    }
?>

Timesheet Controller:

class TimesheetController extends BaseController {      
    private $timesheetRepository;

    function __Construct( ITimesheetRepository $timesheetRepo )
    {
        $this->timesheetRepository = $timesheetRepo;
    }

    ...

    // [HttpGET]
    public /*  */ function GetCreate()
    {       
        return View::make( 'Timesheet/Create' );
    }   

    // [HttpPOST]
    public /*  */ function PostCreate()
    { 
        // To do
    }    
}

Timesheet/Create

@extends( 'layout' )

@section( 'Styles' )
    <link href="<?php echo Request::root(); ?>/Styles/Timesheet.css" rel="stylesheet">
@stop

@section( 'Title' )
    Create timesheets
@stop

@section( 'Content' )

<form role="form">
    <table id="TimesheetTable" class="table">
        <thead>
            <tr>
                <th>Project/Deliverable</th>
                ...                
            </tr>
        </thead>
        <tfoot>
            <tr>
                <td></td>
                ...
            </tr>
        </tfoot>
        <tbody>
            <?php
                for( $a = 0; $a < 18; $a++ )
                {
            ?>
                    <tr id='row<?php echo $a; ?>'>
                        <td><?php /* Get response from DeliverableController/DropdownList */ ?></td>...                    
                    </tr>
            <?php
                }
            ?>
        </tbody>
    </table>
@stop

@section( 'Scripts' )
    <script src="<?php echo Request::root(); ?>/Scripts/Timesheet.js"></script>
@stop

Notice the /* Get response from DeliverableController/DropdownList */

like image 711
Jimmyt1988 Avatar asked Dec 26 '22 12:12

Jimmyt1988


2 Answers

If you would like to call a controller from a view you can use the IOC container

    App::make(//ControllerName)->//methodName(//parameters);

Example:

    App::make("UserController")->displayUsers(array('page_id' => 55));
like image 75
Korush Mahdavieh Avatar answered Dec 28 '22 01:12

Korush Mahdavieh


This far from ideal, but a controller is a class as any other one, so you might be able to:

with(new UsersController)->doWhatever();

But if you are in need of doing something like that looks like your controllers are not really following some design patterns and they might have too much resposibilities, just to enlist some:

1 - A controller should not know much about your business logic. Controllers should receive a request send them to a model (or a repository) the the processed data and provide this data to a view or just redirect the user to another route.

2 - A controller should not be called by any other piece of code than the router itself.

3 - A view should not be aware of your classes and process things, they should receive data (already processed) from controllers and show them.

4 - The single responsibility principle that one should be responsible for doing just one. If your are calling a controller from your view, your view is being responsible for showing AND processing, and your controller is having the responsibility of a normal class (or a model or a repository) and also a controller.

And just with what you've said this list could go on...

What Laravel developers would basically tell you to do:

1 - Create a controller that does almost nothing:

class WhateverController extends Controller {

    private $repository;

    public function __construct(RepositoryInterface $repository)
    {
        $this->repository = $repository;
    }

    public function whatever()
    {
        $data = $this->repository->processData(Input::all());

        return View::make('your.view')->with(compact($data));
    }

}

2 - And everything that you need to do to generate data to your view you do in your repository class. You can have other classes instantiated (or inject) inside your repository to do whatever you need to do:

class Repository implements RepositoryInterface {

    public function processData($input)
    {
        $dataProcessor = new DataProcessor;

        return $dataProcessor->process($data);
    }

}
like image 26
Antonio Carlos Ribeiro Avatar answered Dec 28 '22 03:12

Antonio Carlos Ribeiro