Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

Introducing BladeX View Models

Original – by Freek Van der Herten – 3 minute read

Earlier today we released BladeX, a package that allows you to use Blade components using a Vue inspired syntax. Read all about it in my previous blogpost.

In the latest North Meets South podcast Jacob and Michael discussed BladeX and wondered if the package could be married with view models or Laravel's View Composers. Our team discussed this too last Friday but we decided to release the core features of BladeX first. After the release today it became apparent pretty fast that we needed some sort of view model support in our projects too. So we got to work!

I'm happy to share that v1.1 of BladeX now has support for view models. In this blogpost I'd like to walk you through the feature.

Using view models

View models are used to transform data before a BladeX component is rendered. Let's make the usage clear with an example. We are going to render a select element to render a select element with some countries.

To make a BladeX component use a view model you need to tack on a call to viewModel when you register the component. The class name of the view model is pass to that method.

BladeX::component('select-field')->viewModel(SelectViewModel::class);

Before reviewing the contents of the component and the view model itself, let's take a look first on how we are going to use component.

@php
// in a real app this data would most likely come from a controller
$countries = [
    'be' => 'Belgium',
    'fr' => 'France',
    'nl' => 'The Netherlands',
];
@endphp

<select-field name="countries" :options="$countries" selected="fr" />

Next, let's take a look at what the SelectViewModel::class looks like:

class SelectViewModel extends ViewModel
{
    /** @var string */
    public $name;

    /** @var array */
    public $options;

    /** @var string */
    public $selected;

    public function __construct(string $name, array $options, string $selected = null)
    {
        $this->name = $name;

        $this->options = $options;

        $this->selected = $selected;
    }

    public function isSelected(string $optionName): bool
    {
        return $optionName === $this->selected;
    }
}

Notice that this class extends \Spatie\BladeX\ViewModel. Every attribute on select-field is being passed to the constructor. This passing is being done name based, the name attribute will be passed to a constructor argument named $name, the options attribute will be passed to $options and so on. Any other argument will be resolved out of the ioc container. This can be handy for dependency injection.

All public properties and methods of the view model will be passed to the Blade view that will render the select-field component. Public methods will be available in as a closure stored in the variable that is named after the public method in view model. This is what that view looks like.

<select name="{{ $name }}">
    @foreach($options as $value => $label)
        <option {!! $isSelected($value) ? 'selected="selected"' : '' !!} name="{{ $value }}">{{ $label }}</option>
    @endforeach
</select>

When rendering the BladeX component, this is the output:

<div>
  <select name="countries">
    <option name="be">Belgium</option>
    <option selected="selected" name="fr">France</option>
    <option name="nl">The Netherlands</option>
  </select>
</div>

If you have any remarks of questions about this, let me know in the comments below.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "Introducing BladeX View Models"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.