Using Strongly-Typed Models With The Doc Type Grid Editor

In this tutorial, you will learn how to use strongly typed models within your Umbraco code when content is created within the grid editor using the doctype grid editor.

Getting Started

In this tutorial, I'm assuming you have an Umbraco website set-up, with the doc-type editor package installed and Umbraco Model builder configured and generating your models correctly for you. If you are new Umbraco and you do not know how to do this, then I suggest you read these articles first:

Using Strongly-Type Models With Doc Grid Editor

First, let's make sure we are all on the same page. I assume you have configured your grid editor. as the documentation recommends In 'config' => grid.editors.config. You will have defined a component(s) similar to this:

{
        "name": "Carousel",
        "alias": "CarouselBlock",
        "view": "/App_Plugins/DocTypeGridEditor/Views/doctypegrideditor.html",
        "render": "/App_Plugins/DocTypeGridEditor/Render/DocTypeGridEditor.cshtml",
        "icon": "icon-item-arrangement",
        "config": {
            "allowedDocTypes": ["CarouselBlock"],
            "nameTemplate": "",
            "enablePreview": true,
            "viewPath": "/Views/Partials/Grid/Editors/DocTypeGridEditor/",
            "previewViewPath": "/Views/Partials/Grid/Editors/DocTypeGridEditor/Previews/",
            "previewCssFilePath": "",
            "previewJsFilePath": ""
        }
    }

In your document-type, you will define a new doctype grid editor property. You have generated your models. To render the grid on a page, in your view you use the GetGridHtml() helper:

@Html.GetGridHtml(Model.CurrentPage, "Grid")

If a content editor adds a new carousel into the grid, when the page loads, Umbraco will look within the 'Views' => 'Partials' => 'Grid' => 'Editors' => 'DocTypeGridEditor' folder, for a view based on the doctype alias, in this example the view should be called 'CarouselBlock.cshtml'. The item that is passed to the view is a IPublshedContent, so to turn this into a strongly typed Model, you could write some code like this:

@inherits UmbracoViewPage
@using Namespace.To

@{
    var carouselBlock = new CarouselBlock(Model);
}

@carouselBlock.Header // etc

Issues

As you may have noticed, when you use the grid editor, a controller never triggers and the only way to use a strongly typed code within your view is to write code within your view.  This approach breaks the MVC pattern, where all your logic should be done within a controller and passed to the view.

You might be tempted to just write all your code in your grid views, however, from my experience, you end up not being able to test a lot of your code, you also end up rewriting things.  Say you want to use a component directly on a page, do you create one normal view and one grid view?  How do you share the logic between both?  To get around this, you have two choices... 

Redirect To A Controller From Your Grid View

One is to have no logic or HTML in your grid views.  Instead, you post back to a controller.  

@Html.Action("Carousel", "Component")

(Assuming you have a controller like this:

public class ComponentController : Controller
{
  [HttpGet]
  public ActionResult Carousel()
  {
     // Work As normal
     return PartialView("MyView");
  }
}

View Model

In your grid view, at the top instead of creating a new model and using that directly within your code, create a View model and then do all your logic within there, like so:

@inherits UmbracoViewPage
@using JonDJones.Core.ViewModels.Components

@{
    var viewModel = new CarouselViewModel(Model);
}

Your view model can then look like this:

    public class CarouselViewModel
    {
        private CarouselBlock _accordionBlock;

        public CarouselViewModel(IPublishedContent content)
        {
            Carousel = new CarouselBlock(content);
// Example code
var injected = DependencyResolver.Current.GetService<IMyHelper>(); } public CarouselBlock Carousel{ get; } }

If all your code is wrapped within view models, you can now put all your logic within the class and have minimal logic in your view - except creating the view model.

I tend to prefer to use the controller approach.  I like using dependency injection when building a website.  Dependency injection allows me to test more of my code and it forces a better design.  In the view model approach, if you want to use dependency injection, you need to use ServiceLocator, which is an anti-pattern.  In the controller approach, I can inject any dependencies I need through the constructor, which is a better practice.  

In reality, it's up to you.  It would be great if you could use a grid and a controller out of the box, but that's not possible yet.  Keeping logic out your view is a recommended pattern to follow.  Using one of the approaches above will allow you to do just that.  Enjoy!

submit to reddit

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top