I'm developing a large scale application. Initially my approach was confused , I am a beginner in javascript even if I develop since January.
I was looking for an mvc approach and I found some guide lines, like :
Model : contains AJAX call , and services
Controller: e.g. jQuery widget and so on
View: e.g. rendering of HTML and so on..
I don't really have clearly how to structure a javascript application following perfectly the three above suggestions. I can do everything, I can manage template I can write jQuery manipulation , I can do AJAX call.
What is not clear to me is how to get really divided these three modules. When I try this approach I'm not able to make any module to do only what it has to do.
I tried also an MV* approach which, for what I see and for my needs maybe it's a better approach, because I have to do bind tons of divs , generate events , all by client side, receiving only data from server side.
What I would like to know:
Which are the really competences of each Module?
If, for example, I have to bind a click event to a button , where do I have to write the
.on('click',callback)
method? Where I have to write the callback he's gonna call?
I wrote : no framework because I'm sure that if I don't understand an approach writing it from scratch, its impossibile I will completely understand the use of a complete framework.
I hope that my doubts were clear, if not, please comment, I'll try to explain better if I can.
Sorry for my english in any case.
This is not an answer because there is no one answer. I just want to mention a few do's and don't's.
Do store pure data in the model. Think of it as business objects rather than display objects. For example, money should be stored in the model as a number, probably with some digits after the decimal point, plus an indicator of what currency it is, if that matters. Don't store the number as a string with local choices of the characters to separate the 1000's and the integer part from the fractional part and the right number of digits after the decimal point.
Do put the handler code for the click events (and similar user actions) in the controller.
Do put the code that causes updates the screen on load or on any external event in the controller. (An external event might be something like an update to a stock price due to stock exchange data or an update to the weather report coming into the application.)
Do put the HTML or the code that generates HTML as part of the view.
Do have the controller call the view to get the display updated/changed at the right times.
Do have either the controller or the view call the model to get the current model data values or the update the the current model data. (See similar "don't" below.)
Do reduce the connectivity between the three parts--M, V and C. Define clearly who can talk to whom for what purpose and keep that rule sacred. If you find an exception, its a smell indicating a problem with the big picture of those rules.
And some more things
Don't put the code that displays the screen on load in the controller. That's clearly a view concern. This means the controller has to call into the view somehow.
Don't spaghetti connect the M, V and C code in random fashions. For example, you might make a rule that the model never calls code in the view or controller.
Don't have both the controller and the view talking to the model.
Questions:
Where does the code go that hooks up the event handlers?
Where do you put the "business logic"? This is the code that knows the rules of your application. Validation, for example, is business logic. Some code may need to know how zip codes look for the US and postal codes for the UK or Canada. If the validation fails, the controller is the one that tells the view to show an error message or red mark or vibrating box or whatever. Does the business logic of validation rules also go in the controller?
Where does the code go that loads data from external data sources? (servers, JSON web services, databases, screen scraping, etc.) You might think "model" but then the model has to call into the controller when new data comes back to tell it to update the view. That doesn't seem right.
Similarly, what is the code that handles the equivalent of a "submit" button, moving to another screen.
If converting data from a form that is displayable on the screen to a form that is pure data is too slow, what do you do?
There are always self-contained portions of the screen that can be built with their own MV&C. How do you set up interactions between multiples of those little MVCs and the big MVC that is the whole screen? Are those little guys the views for the big MVC? Or are the controllers? Can they be both at once? Is there a big model with the little models in it or does data flow between little models and big models? Who knows about all this?
Is there an even bigger MVC comprised of multiple screens? It would probably be on the server if it exists.
How do you handle "synthetic" events? This is something like an "event" that occurs when the data was ok but is now in a bad state (or was incomplete and is now complete). Listeners to this event can disable the "Submit" button and display error messages or animations calling the user attention to the problem. It could be anything that isn't a generic event built into the framework or language. Perhaps its a message to the server indicating a change in the state of a multiplayer game's world view.
This is just a list of things that pop to mind when you are writing your own MVC or when evaluating an existing framework.
There is no clear answer outside a specific framework. Although the general responsibilities of the MVC pattern are (almost) clear to everyone, each framework has its own interpretation of exactly what pieces of code to put in each of these layers - some frameworks even skip some layers, or add different ones instead.
I know you don't want to use a framework, but still, it's worth to have an overview of how the current solutions work, so you can make an informed decision if you like the way they work or if you prefer to roll your own.
I recommend you at least take a look at one server side MVC framework (such as Ruby on Rails or Asp.Net MVC) and some client side MVC frameworks too (Backbone.js, Angular.js, etc. - javascript only). Read their documentations, and learn from the choices others have made (and tested). The site todo mvc can help you to compare different client MVC frameworks to find the approach you like better.
This is not a simple topic, and discussing the pros and cons of each approach from scratch can take forever.
Related
I have a contract job for editing a Django application, and Django is not my main framework to use, so I have a question regarding models in it.
The application I am editing has a form that each user can submit, and every single model in the application is edited directly through the form.
From this perspective, it seems every model is directly a form object, I do not see any model fields that I could use for custom variables. Meaning instead of a "string" that I could edit with JS, I only see a TextField where the only way it could be edited is by including it on a form directly.
If I wanted to have some models that were custom variables, meaning I controlled them entirely through JS rather than form submissions, how would I do that in Django?
I know I could, for example, have some "hidden" form objects that I manipulated with JS. But this solution sounds kind of hacky. Is there an intended way that I could go about this?
Thanks!
(Edit: It seems most responses do not know what I am referring to. Basically I want to allow the client to perform some special sorting functions etc, in which case I will need a few additional lists of data. But I do not want these to be visible to the user, and they will be altered exclusively by js.
Regarding the response of SColvin, I understand that the models are a representation of the database, but from how the application I am working on is designed, it looks as if the only way the models are being used is strictly through forms.
For example, every "string" is a "TextField", and lets say we made a string called "myField", the exclusive use of this field would be to use it in templates with the syntax {{ form.myField|attr:"rows:4" }}.
There are absolutely no use of this model outside of the forms. Every place you see it in the application, there is a form object. This is why I was under the impression that is the primary way to edit the data found in the models.
I did the Django tutorial prior to accepting this project but do not remember seeing any way to submit changes to models outside of the forms.
So more specifically what I would like to do in this case: Let's say I wanted to add a string to my models file, and this string will NOT be included/edited on the form. It will be invisible to the user. It will be modified browser-side by some .js functions, and I would like it to be saved along when submitting the rest of the form. What would be the intended method for going about doing this?
If anyone could please guide me to documentation or examples on how to do this, it would be greatly appreciated! )
(Edit2: No responses ever since the first edit? Not sure if this post is not appearing for anyone else. Still looking for an answer!)
There is some terminology confusion here, as SColvin points out; it's really not clear what you mean by "custom variables", and how those relates to models.
However your main confusion seems to be around forms. There is absolutely no requirement to use them: they are just one method of updating models. It is always possible to edit the models directly in code, and the data from that can of course come from Javascript if you want. The tutorial has good coverage of how to update a model from code without using a form.
If you're doing a lot of work via JS though, you probably want to look into the Django Rest Framework, which simplifies the process of converting Django model data to and from JSON to use in your client-side code. Again though DRF isn't doing anything you couldn't do manually in your own code, all without the use of forms.
I've been using KnockoutJS for some time now, mainly on small-to-medium sized projects. However, I'm now working on a very large project with many different views of the same data. For example, a product may be displayed to the customer, allowing them to add products to their shopping cart, and also to an administrator, allowing them to edit the product name, price and available stock. I want to be able to use the same model in both cases, but designing a solution with KnockoutJS is proving difficult. Specifically, I am having two issues:
I want to be able to re-use certain "view" functionality without repeating myself. For example, in both the customer- and administrator- view of products, clicking the product thumbnail displays the product image in fullscreen. Instead of each view containing the same verbose binding code (e.g., <img data-bind="event:{click:function codeToZoom(){}}"/> in both views), I can move the binding information to the model itself. So the above becomes <img data-bind="event:imageEvents()"/>. However, doing the above forces me to include code that responds to user input in my model, which violates the single-responsibility principle - e.g., the model is reponsible for business logic, not responding to user input. If I decided I wanted an administrator clicking the thumbnail to open an "Upload New Image" dialog, then I'd need to implement a imageEventsForAdministrator() function.
I've asked people how they deal with the above, and their answer has been "Write two different models." This sounds good until you realise that a product has a lot of embedded logic, and writing two different models forces you to duplicate that logic. So:
According to KnockoutJS, what is the recommended approach for separating business logic from responding to events/user-input?
Your post is interesting and understandable... yet really rather broad for Stack Overflow.
To answer some of your more specific subquestions though:
I want to be able to re-use certain "view" functionality without repeating myself.
There are two typical constructs for tackling this issue:
Use templates to do so. Knockout will keep the template as a "prototype" view, and instantiate new instances (and clean up) as needed.
Load view html dynamically as "partial views" if you will, and use the appropriate applyBindings overload to render those bits only when needed.
For example, [...] clicking the product thumbnail displays the product image in fullscreen [...] <img data-bind="event:{click:function codeToZoom(){}}"/> in both views
Well, there's several options here. I find that if you want you can actually de-duplicate code as much as theoretically possible. First, you can usually do this:
<img data-bind="event:{click: myHandler}"/>
And you can use some kind of prototypical or classical inheritance on your view models to make sure myHandler is only defined once.
Again, if you find yourself repeating the <img... bit: use KO templates.
Moving on:
This sounds good until you realise that a product has a lot of embedded logic, and writing two different models forces you to duplicate that logic.
In that case you're probably violating the SRP. You probably need to take that logic out of your view models and place it somewhere else (e.g. in controllers, DALs, etc.). But that topic is really broad, our sister site has an entire tag dedicated to it.
Finally, you ask:
According to KnockoutJS, what is the recommended approach for separating business logic from responding to events/user-input?
KnockoutJS recommends no particular approach.
That is, KO is an MVVM library, and as such does nudge you in a certain direction, but it doesn't really force you to take any particular approach with this. It's really up to you to write and structure infrastructure and code for common business logic, think up a good inheritance strategy or something similar, etc.
So it's up to you.
As a footnote, if you haven't already, I'd recommend running through some AngularJS tutorials as well. It has MVVM style bindings, but it is IMO more opinionated about how to solve the problems you're facing. (This is not advice to switch; merely advice to find inspiration in KO-alternatives.)
We developed a WEB based application using Knock out and Pager JS. We are almost to the end of the project. We have only one view model that serves the data binding for all data elements shown on UI screen. We are looking out for the options to split the JS files to make it more efficient and readable. Since we have only one view model that serves the whole data binding, its easier for us to call same methods for different actions using self.methodName();. My Questions are below,
1) If we are going to split up the View models into multiple files, how do we invoke a method from one view model to another view model.
2) I was checking abt the namespace to split the files using knockout, but not sure how far it works?
3) Some recommendation using require js, I seen some examples.. but not sure whether that will resolve the issue.
We are apply the databinding like below,
window.VM = new viewModel();
ko.applyBindings(window.VM);
4) If the content of the data is been shared with mutliple screens, how do we bind for each div.. for example, if I want to show the contact detail screen in Contact Detail and also subset of contact Detail information... How do we acheive it.. Based on my understanding, the databinding applies to a div element.. If I want to show the same data on two different screen, how we will acheive this...
Sorry for asking everything in one question..
Thanks,
Ramesh
Definitely you have to read about PubSub concept, which is easy implementable with KO.
E.g. http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html
I've just started using Spine.js. I like it.
But sometimes I just need to make a simple call to the backend to get JSON data to fill, say, a navigation bar that won't be changing after it gets populated. Here, making a front end model and controller seem like overkill, when I could just use a simple jQuery call and push the JSON response into a template and inject the result into the DOM.
Is there any disadvantage to this hybrid approach, where some of the view gets managed by JavaScript MVC and others just get injected by simple jQuery Ajax code?
The whole idea behind MVC is separation of concerns. A Model handles data, a View handles display, and a Controller handles flow and in some cases business logic. Sure, you could easily make that jQuery call within your view; after all, JavaScript is wide open, and as long as you can get a reference, you're free to do what you want. But doing that defeats the pattern and muddies the waters of the role your view plays. All in all, if you adopt the design pattern, stick to it. It'll make managing your application months or even years from now a lot easier because you won't have to think about the roles of your components.
I say you should do it for all.
I don't think your choice should be a matter of the difficulty of doing so, its that if you establish a standard, stick to it. Doing so usually saves time in the end.
Well, the first question I always ask when confronted with one-time injected JS is whether that shouldn't happen on the back end in the first place.
As for the matter of consistency, if it takes very little effort to do it the 'wrong' way, go ahead and see what happens. It's not like it will be a ton of work to change it later if needed and I really don't see why you'd burn time and/or unnecessary overhead to your app just to be consistent.
The important thing is that you make it obvious you're not handling that via the MVC approach in your code for the next dev. But at the end of the day, the tool is there to help, not hinder you. We all make some exceptions on the separation of concerns where css, html and JavaScript are concerned as well. The important thing is to understand the true value of the rule so you know what the tradeoff is when you break it. In this case, I don't see much of one.
How is your javaScript code organized? Does it follow patterns like MVC, or something else?
I've been working on a side project for some time now, and the further I get, the more my webpage has turned into a full-featured application. Right now, I'm sticking with jQuery, however, the logic on the page is growing to a point where some organization, or dare I say it, "architecture" is needed. My first approach is "MVC-ish":
The 'model' is a JSON tree that gets extended with helpers
The view is the DOM plus classes that tweak it
The controller is the object where I connect events handling and kick off view or model manipulation
I'm very interested, however, in how other people have built more substantial javaScript apps. I'm not interested in GWT, or other server-oriented approaches... just in the approach of "javaScript + <generic web service-y thingy here>"
Note: earlier I said javaScript "is not really OO, not really functional". This, I think, distracted everyone. Let's put it this way, because javaScript is unique in many ways, and I'm coming from a strongly-typed background, I don't want to force paradigms I know but were developed in very different languages.
..but Javascript has many facets that are OO.
Consider this:
var Vehicle = jQuery.Class.create({
init: function(name) { this.name = name; }
});
var Car = Vehicle.extend({
fillGas: function(){
this.gas = 100;
}
});
I've used this technique to create page-level javascript classes that have their own state, this helps keep it contained (and I often identify areas that I can reuse and put into other classes).
This is also especially useful when you have components/server controls that have their own script to execute, but when you might have multiple instances on the same page. This keeps the state separate.
JavaScriptMVC is a great choice for organizing and developing a large scale JS application.
The architecture design very well thought out. There are 4 things you will ever do with JavaScript:
Respond to an event
Request Data / Manipulate Services (Ajax)
Add domain specific information to the ajax response.
Update the DOM
JMVC splits these into the Model, View, Controller pattern.
First, and probably the most important advantage, is the Controller. Controllers use event delegation, so instead of attaching events, you simply create rules for your page. They also use the name of the Controller to limit the scope of what the controller works on. This makes your code deterministic, meaning if you see an event happen in a '#todos' element you know there has to be a todos controller.
$.Controller.extend('TodosController',{
'click' : function(el, ev){ ... },
'.delete mouseover': function(el, ev){ ...}
'.drag draginit' : function(el, ev, drag){ ...}
})
Next comes the model. JMVC provides a powerful Class and basic model that lets you quickly organize Ajax functionality (#2) and wrap the data with domain specific functionality (#3). When complete, you can use models from your controller like:
Todo.findAll({after: new Date()}, myCallbackFunction);
Finally, once your todos come back, you have to display them (#4). This is where you use JMVC's view.
'.show click' : function(el, ev){
Todo.findAll({after: new Date()}, this.callback('list'));
},
list : function(todos){
$('#todos').html( this.view(todos));
}
In 'views/todos/list.ejs'
<% for(var i =0; i < this.length; i++){ %>
<label><%= this[i].description %></label>
<%}%>
JMVC provides a lot more than architecture. It helps you in ever part of the development cycle with:
Code generators
Integrated Browser, Selenium, and Rhino Testing
Documentation
Script compression
Error reporting
MochiKit is great -- and was my first love, so-to-speak, as far as js libraries go. But I found that while MochiKit has very expressive syntax, it didn't feel nearly as comfortable to me as Prototype/Scriptaculous or jQuery did for me.
I think if you know or like python, then MochiKit is a good tool for you.
Thank you all kindly for your answers. After some time, I'd like to post what I've learned so far.
So far, I see a very large difference the approach using something like Ext, and others like JQuery UI, Scriptaculous, MochiKit, etc.
With Ext, the HTML is just a single placeholder - UI goes here. From then on, everything is described in JavaScript. DOM interaction is minimized under another (perhaps stronger) API layer.
With the other kits, I find myself starting by doing a bit of HTML design, and then extending the DOM directly with snazzy effects, or just replacing the form input here, an addition there.
The major differences start to happen as I need to deal with event handling, etc. As modules need to "talk" to each other, I find myself needing to step away from the DOM, abstracting it away in pieces.
I note that many of these libraries also include some interesting modularization techniques as well. A very clear description is contributed on the Ext website, which includes a fancy way to "protect" your code with modules.
A new player I haven completely evaluated is Sproutcore. It seems like Ext in approach, where the DOM is hidden, and you mostly want to deal with the project's API.
Tristan, you will find that when you try to architecture JavaScript as an MVC application it tends to come up short in one area -- the model. The most difficult area to deal with is the model because the data does not persist throughout the application, and by nature the models seem to change on the client-side pretty consistently. You could standardize how you pass and receive data from the server, but then at that point the model does not really belong to JavaScript -- it belongs to your server-side application.
I did see one attempt awhile back where someone created a framework for modeling data in JavaScript, much like the way SQLite belongs to the application. It was like Model.select( "Product" ) and Model.update( "Product", "Some data..." ). It was basically an object notation that held a bunch of data to manage the state of the current page. However, the minute you refresh, all that data is lost. I'm probably off on the syntax, but you get the point.
If you are using jQuery, then Ben's approach is really the best. Extend the jQuery object with your functions and properties, and then compartmentalize your "controllers". I usually do this by putting them into separate source files, and loading them on a section-by-section basis. For instance, if it were an e-commerce site, I might have a JS file full of controllers that handle functionality for the checkout process. This tends to keep things lightweight and easy to manage.
Just a quick clarification.
It is perfectly feasible to write GWT apps that are not server-oriented. I am assuming that from Server-Oriented you mean GWT RPC that needs java based back-end.
I have written GWT apps that are very "MVC-ish" on the client side alone.
The model was an object graph. Although you code in Java, at runtime the objects are in javascript with no need of any JVM in either client or server-side. GWT also supports JSON with complete parsing and manipulation support. You can connect to JSON webservices easily, see 2 for a JSON mashup example.
View was composed of standard GWT widgets (plus some of our own composite widgets)
Controller layer was neatly separated from View via Observer pattern.
If your "strongly-typed" background is with Java or similar language, I think you should seriously consider GWT for large projects. For small projects I usually prefer jQuery. Upcoming GWTQuery that works with GWT 1.5 may change that though not in near future because of abundance of plugins for jQuery.
Not 100% sure what you mean here, but I will say that after doing ASP.NET for the last 6 years, my web pages are now mostly driven by JavaScript once the basic page rendering is done by the server. I use JSON for everything (have been for about 3 years now) and use MochiKit for my client-side needs.
By the way, JavaScript is OO, but since it uses prototypical inheritance, people don't give it credit in that way. I would also argue that it is functional as well, it all depends on how you write it. If you are really interested in functional programming styles, check out MochiKit - you may like it; it leans quite a bit towards the functional programming side of JavaScript.