Skip to content
No description or website provided.
Java Groovy
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
grails-app
src/java/grails/plugin/viewmodels
test/integration
web-app/WEB-INF
.gitignore
LICENSE.txt
README.md
ViewModelsGrailsPlugin.groovy
application.properties

README.md

The “View Models” plugin provides some support for something like the Model-View-ViewModel pattern, referred to as MVVM (for some background see this Wikipedia article).

About MVVM

Since Grails is already founded on the MVC pattern, the idea of MVVM takes on a slightly different meaning to what it does to desktop developers. In the context of a Grails application, a “View Model” is an abstraction of the view oriented properties of an aspect of the application model.

Consider the following example. Your application lists one or more products on a screen. If the price of a product is less than $10, you want the product name to display in a different colour. Where does this characteristic belong? It most certainly does not belong on your Product domain class for obvious reasons. There are two feasible options; a taglib or a snippet of Groovy code in the view GSP. Using a taglib is a reasonable choice here, but taglibs are inconvenient to test and it doesn't seem right to create a tag to do a calculation (i.e. tags are inherently focussed on creating HTML representations of things). Using inline snippets of Groovy is very convenient, but difficult to test and prone to decay over time.

The MVVM pattern (as we are interpreting it) suggest that a specialised object should be created that implements the view level concerns of the product. Enter ProductViewModel.

class ProductViewModel {
    Product product

    ProductViewModel(Product product) {
        this.product = product
    }

    String getNameColourName() {
        product.price < 10 ? "red" : "black"
    }
}

Now instead of passing your Product instance to the view, you pass an instance of ProductViewModel.

class ProductController {

    def list = {
        [products: Products.findAll().collect { new ProductViewModel(it) }]
    }

}

Plugin Features

It's possible to roll your own view model type objects without any special plugins or magic. To do this you would likely create some classes in the src/groovy directory and manually instantiate them. While this would work, you don't get development time reloading and autowiring which you probably can't live without if you are like me. This plugin provides these two features.

All view model class MUST be in the grails-app/viewModels directory and MUST end in the suffix “ViewModel” (e.g. ProductViewModel).

Autowiring

This plugin uses Groovy's MOP to augment existing constructors to provide dependency injection autowiring, and general Spring initialisation (e.g. calling afterPropertiesSet() on view models implementing InitializingBean) . This includes supporting any custom constructors, not just no-arg constructors like Grails domain classes.

class BookViewModel {
    def bookService
    def book

    BookViewModel(Book book) {
        this.book = book
    }
}

def bookViewModel = new BookViewModel(Book.get(1))
assert bookViewModel.bookService != null

This also works with the default Groovy map constructor…

class AuthorViewModel {
    def authorService
    def author
}

def authorViewModel = new AuthorViewModel(author: Author.get(1))
assert authorViewModel.authorService != null

Autowiring occurs after the constructor has completed.

Initialisation

After autowiring has occurred, the usual initialisation methods will be called on the view model instance via the initializeBean method.

Reloading

View model classes can be hot reloaded during development time, like services and controllers.

Licensing

The plugin is released under the Apache License 2.0.

Something went wrong with that request. Please try again.