Reputation: 31
I'm trying to get a practical grasp of MVC model implementation (not the conceptual understanding) in JavaScript.
As for the start, I thought it would be worth making an effort and try building a MVC app in plain JS. I've read dozens of articles and book chapters referring to MVC and its variations. Of course I googled lots of examples to see how it's done for real. The most understandable and with the proper meaning is in my opinion this one:
https://github.com/tastejs/todomvc/tree/master/examples/vanillajs
In the end, I was able to refactor my own app in the todomvc-vanillajs way.
However, there is one thing that still bothers me. All these apps and examples are very basic, so there is only one Model, View and Controller specified for the whole app.
What if I wanted to add more (equally complex) features to such app?
Should I add them one by one to my controller.js view.js and model.js files or whether should I stop developing spaghetti code and add new files instead, thus creating new models, controllers and views for each of the new feature individually?
It seems to me, that every feature should have its own view, controller and model, or at least, could have, depending on the subjective evaluation. But I'm not quite sure how such implementation should look at this situation in terms of code structure, namespacing etc.?
What if I want to imitate a scale by creating multiple views, models and controllers on every single functionality like e.g. handling an "add task to the list" or "delete the task" actions.
For the purpose of my dilemma, I've created my own MVC draft, which has two models, controllers and views. Whether such an approach would make sense? What happens when further developing my application, I quickly get to the point where I have dozens and more specific (coresponding) models, views and controllers.
Heres is the aforementioned fiddle.
;(function () {
'use strict';
/**
* @file ./App.js
*/
var App = {
Model : {},
Controller : {},
View : {}
};
console.log('start');
window.App = App;
})();
/* -------------Views-folder----------------------*/
/* -------------separate-file-----------------------*/
(function () {
'use strict';
/**
* @file Views/buildAdd.js
*/
var buildAdd = {
// render
// event
// pass the reference to event handler in Controller
};
App.View.buildAdd = buildAdd;
})(App);
/* -------------separate-file-----------------------*/
(function () {
'use strict';
/**
* @file Views/buildDelete.js
*/
var buildDelete = {
// render
// event
// pass the reference to event handler in Controller
};
App.View.buildDelete = buildDelete;
})(App);
/* -------------Controllers-folder----------------------*/
/* -------------separate-file-----------------------*/
(function () {
'use strict';
var addController = {
// handle the event and decide what the Model has to do
// handle the response from Model and tells the View how to update
};
App.Controller.addController = addController;
})(App);
/* -------------separate-file-----------------------*/
(function () {
'use strict';
var deleteController = {
// handle the event and decide what the Model has to do
// handle the response from Model and tells the View how to update
};
App.Controller.deleteController = deleteController;
})(App);
/* -------------Models-folder----------------------*/
/* -------------separate-file-----------------------*/
(function () {
'use strict';
var addModel = {
// send request
// get response
};
App.Model.addModel = addModel;
})(App);
/* -------------separate-file-----------------------*/
(function () {
'use strict';
var deleteModel = {
// send request
// get response
};
App.Model.deleteModel = deleteModel;
})(App);
/* -------------separate-file-----------------------*/
Thus, I found this question very similar to mine, but the provided answers are not entirely satisfactory, at least to me.
Upvotes: 3
Views: 4769
Reputation: 27460
Check my implementation of so called Single Page Application framework. The whole thing is of 60 lines of code. It uses jQuery but can be implemented in VanilaJS.
Basic idea is simple - your app is just a collection of pages a.k.a. views
<section id="route1" src="content1.htm" />
<section id="route2" src="content2.htm" />
...
Sections id's define set of possible "routes" SpAPP catches browser's navigate event and load requested view on the route.
And partial content1..N.htm files contain view markup, setup and controller functions.
Data model here is JS data received from server and stored in memory or in local storage.
As of MVC frameworks in general... You cannot bring joy to everyone and free of charge. That small SpAPP thing that can easily be understood and adjusted to particular project's needs is a way to go I think.
Upvotes: 3
Reputation: 625
Looking at my experience in Ruby on Rails framework, I don't always need all three elements of MVC pattern. Sometimes you need a model for a database but it's only accessed internally, not by the client. Or sometimes you only need a generic helper class.
As a convention, the files are split, each one has its own controller, model and view, following a naming convention, maybe something like:
articles-view.html
articles-controller.js
articles-model.js
Views are split for each action in the controller:
articles-index.html
articles-show.html
articles-update.html
...
articles-controller.js
articles-model.js
Inside the controller, you will have the "actions", the functions for everything semantically related to an Article in a blog.
function ArticlesController() {
function index() { ... }
function create() { ... }
function edit() { ... }
...
function delete() { ... }
}
In models, you basically have the class / prototype itself, something that is built with the given data.
function Article() {
this.name = "";
this.author = "";
this.text = "";
this.dateCreated = "";
}
And finally, your views should have element with the same name used in the model.
If you have a basic CRUD system, for example, you can have just one controller and one model, but different views (one for listing all items, one for creating and editing, one for just one item, etc). Taking examples from Rails and NodeJS, a way to write less code for the views is by using "partials". Common HTML structures can be saved on a file and imported into other HTML files as needed, such a form, the headers, the footer of a page and so on.
Example: Instead of having a form on articles-create.html and another on articles-edit.html, you will have something like:
_articles-form.html <- this is your partial!
articles-create.html
articles-edit.html
"_articles-form.html" will be imported / appended into the create and edit pages.
Other common features can be consider as "Helpers". They are not a letter in "MVC", but often used. Like the Datepicker library, a simple validation function, a parser, etc. Something that can be used by everyone, not a specific feature of a class.
The project structure could be something like:
Also, having a Manager functionality as you described above, will help you load all the data needed. Some function that maybe will read a json file, looking for the feature's name and parsing through the file's names, loading everything.
The manager would check if there is a model file, a controller file and a folder with N view files in it, containg the word "articles". The same would happen to "authors", "comments", "users" and so on.
I understand that you are proposing this question for study reasons and you took JS as a personal preference, so I´m not saying "don't try it" or something like that. But something to consider: the MVC pattern tackles applications that involves both client and server side. Unless your are developing on a full stack with NodeJS and MongoDB (or other similar technologies), HTML and Javascript are more on the View side of the application (or as helpers).
And if you are developing something like a library, you'll end up putting everything on a single file and minifying/uglifying it. Take JQuery as an example. Javascript developers often go with the Module pattern. They create an object, expose methods and variables that the other developer needs to know and that's it.
So, probably (but not for sure, you never know!), you won't see or work on many vanilla Javascript applications implementing MVC pattern.
Upvotes: 1