Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
ViewModels
  • Hello. I am new to FuelPhp. I don`t understand what are ViewModels(I see the documentation).
  • Viewmodels are classes that encapsulate a view, and which sometimes is called a Presenter.

    The idea is that you keep your views free of any logic, other then the logic needed to create the page (foreach and if structures), but also keep logic specific for the view out of the Controller.

    For example, say you have a view that creates a page header. Besides the menu, it also has a login/logout option, and when a user is logged in, the name, group and login time info of that user.

    In the traditional model you would do all this work in the Controller (or if you are very bad, in the view). With the Viewmodel, you would only pass the userid from the Controller to the Viewmodel (or null if no user is logged in). All logic needed to get username, group, time, and formattting of that happens in the Viewmodel, which is then passed on to the view, that only needs to echo it.

    So it's a View abstraction layer.
  • In other php frameworks there are no such thing like Viewmodels as you said. But I cant get it. Please explain it more specific. I am very new to mvc patterns. I like the syntax of Fuelphp but some parts of documentation are puzzle for me. Give me some practical example.
  • HarroHarro
    Accepted Answer
    I think the docs explain it quite well: http://fuelphp.com/docs/general/viewmodels.html

    If it makes it easier, try to imagine using a View parser like Smarty or Twig, where you don't have PHP in your views. This means you can not put any processing logic in your views.

    Question is, where do you put your logic then? In most other frameworks, you put it in the controller. A controller method becomes hunderds of lines, starting with fetching some data (using models I hope), and the rest of the code processing that data so it can be send to the View for display.

    We believe that this logic does not belong in the controlller, it is logic that is completely tied to the View. And this is what the Viewmodel does. You pass it raw data, it processes it to the properties the View needs to display.

    Note that you are not required to use a Viewmodel. If you don't see it's benefit, you don't have to, you can use Fuel like you would any other framework, Fuel gives you that flexibility.
  • Another example is using multiple layout, for example browser and mobile.

    Your controller should not be bothered with this, it gets the requests, fetches the data, sends it to the Viewmodel, job done. The Viewmodel can (for example based on data of the Agent class) decide to load different views based on the size of the browser viewport, and pass different data elements to those views.

    This means your application can be made multi-platform without having to change a single line of controller logic.
  • Thank you.
  • That would be more like a filter.

    Take for example an invoice. It has invoice header info (client name, invoice number, etc), and you have invoice lines  (quantity, product, price per item, VAT code). So your controller would do:

    $invoice = Model_Invoice::query()
        ->where('id', '=', $invoice_id)
        ->related('invoicelines')
        ->related('invoicelines.vatcodes')
        ->get();

    Now in your view, you need to display this, but it needs preprocessing. You need to fetch the VAT percentage linked to the code, you have to calculate the total from the price per item and the quantity, you have to calculate incl. and excl. VAT prices, and you need invoice totals incl. and excl. VAT, and totals of VAT per VAT code.

    So the next line in your controller will be

    return \Viewmodel::forge('invoices/show')->set('invoice', $invoice);

    which will create the Viewmodel instance, creates the associated 'invoices/show' View object, passes the raw invoice object and it's related objects, and returns it for display.

    Then in the Viewmodels view method, you do all your calculations:

    public function view()
    {
        $this->total = 0;
        foreach ($this->invoice->invoicelines as $line)
        {
            $this->total += $line->quantity * $line->price;
        }
    }

    Now your Viewmodel object has a "total" property which will be accessable by the view.

    So finally in your view you can do:

    The total amount on this invoice is <?php echo $total; ?>

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion