mercredi 14 décembre 2016

Properly separating the data model and view model

I am asking this in the context of AngularJS, but this question could really be applied to any language. So in a web application we have a use case where we need to fetch some data from a server (HTTP request) and then display that data in the UI.

So lets say our application is displaying a list of Books. Our process would look like this:

  1. Run a GET request to /api/books to get a list of all our books
  2. (optional) Transform the server-data-model to a client-data-model if needed
  3. Bind the models to the $scope so they are accessible via the view
  4. Iterate through the models on the $scope and display them in the HTML

At this point lets say we have a simple list of checkboxes with a book title next to it like this:

<ul>
    <li ng-repeat="book in vm.Books">
        <input type="checkbox" ng-model="<HERE>" name="my-books" />
        <label></label>
    </li>
</ul>

As you can see, in this template we reference the book.title in order to display it in the page. However, you can also see that the ngModel is unknown. This is where I am not sure what to do. The simple solution is to just tack on a UI model for use in the UI. This means that in step 2 above we would do book.UI = {} to every single model, then when we need to send that model back to the server we would have to do delete book.UI to clean it back up.

Doing this would allow our template to look like this now:

<ul>
    <li ng-repeat="book in vm.Books">
        <input type="checkbox" ng-model="book.UI.isSelected" name="my-books" />
        <label></label>
    </li>
</ul>

Now we can control when a book is selected via the checkbox input. This work OK, but it doesn't separate our concerns enough and there are side effects to using this pattern.

I'm sure there is a abstract design pattern that could solve this that isn't implementation specific, I just am not aware of any myself. Does anyone have any advice on how to obtain this kind of flexibility in the front end but separates our view models and data models completely so we don't have to do any "clean up" work?

Aucun commentaire:

Enregistrer un commentaire