JavaScript MVC – Client-side Separation of Model and ViewModel in JavaScript

javascriptmvcmvvm

I am developing web apps using the Model-View-ViewModel approach with Knockout.js. After reading on the original introduction of MVVM by John Gossman, I realized that my ViewModel always contains ALL the app's logic, not only UI logic, but everything.

I've read somewhere that with Knockout, the model is considered the database or generally the data on the server. But according to MVC, the model also contains functions which do some processing with that data and are not UI-related.

So I wondered if it would be reasonable to have a separate Model object independent from the ViewModel object? The idea behind this would be that the ViewModel would contain UI logic only (as intended by Gossman) and the Model would contain business logic only (as in MVC), which has nothing to do with the actual View. Example:

var viewModel = {
    hint: ko.observable("Idle"), //text visible in the View
    buttonClicked: function () {
        this.hint("doing stuff");
        model.doStuff();
        this.hint("done");
    }
};

var model = {
    doStuff: function () {
        //business logic, UI independent
    }
};

Is there a recommendation or "best practice" which can be derived from the MVVM pattern definition?

Best Answer

Are you over-architecting your app?

MVVM is a great way for organizing logic for an application that would otherwise become too complicated. But sometimes it can be overkill.

You mention you end up having all the model logic in the ViewModel, and that doesn't seem to be giving you any problems. If there's no practical reason you need to separate your View and ViewModel, then maybe classic MVC would be sufficient for your app.

Using MVVM Anyway

If you want to tackle MVVM now, what you've got so far is a fine place to start. It's actually similar to what happens on my team: the VM gets done first (along with the View and some dummy data). Then once the back end (the database and API) is done, we migrate the business logic from the ViewModel to the Model.

The article you read that said the model "is" the database simplifies the matter a little too much. The model would be the place, for example, to have functions to calculate local taxes.

The Model should contain all the logic you would need if you were going to present the information in a separate view - for instance, if you were going to write a dedicated mobile site, you might reuse the Model but rewrite the ViewModel.

My suggestion is you try separating the Model and ViewModel a few times, and see if you start to see benefits from doing so. It might be premature optimization, but you probably don't know until you try.

Signs you might need a ViewModel

Here are a few signs it may be time for a ViewModel:

  • There's complex logic (e.g., conditions) in your View, or big blocks of "non-inline" code.
  • You are collecting functions in your model that are only useful in certain contexts (this page but not that page)
  • Your controller is getting cluttered with code that doesn't seem like a fit for either your view or model
Related Topic