I'm in the process of trying to wrap my head around using MVC and using it with javascript. I'll be making a mobile app with HTML5 and don't plan to use any server side languages only local storage.
How can this be achieved?
I'm usually thrown off by the model since it relies on the back end language from my understanding.
The Model doesn't rely on the back end. MVC in conceptually simple:
Controller gets request.
Controller calls for Model to do all of the logic (be it database interaction, localStorage interaction of whatever)
Model returns data to Controller.
Controller calls View accordingly, and if needed, passes data from the Model.
This means, that Model doesn't have to use a server side language, it's a placeholder for the application logic.
There are multiple MV* frameworks available. You don't have to have server support to use them.
BackboneJS
EmberJS
javascriptMVC
There are many more, but these three come to mind first. Enjoy
MVC development has nothing to do with server side scripting.
It only relate to the type of architecture you are taking to develop your application.
It only means you have Models, Views and Controllers. Models can be object generated from javascript which are used with the Views in order to render some data.
Controllers are there to hold the logic and behaviour between the view and the models.
Well that's a very basic overview, but by no means does MVC means backend services or ajax calls.
This article might help http://www.alexatnet.com/articles/model-view-controller-mvc-javascript
Related
In a .Net MVC world, we have access to model data at the view level, and can easily make use of Razor syntax to iterate through lists, etc. However, with the incorporation of a js framework like AngularJS, a shift in data access is considered:
Make all data request RESTful requests, and consume JSON data through Angular factories, etc.
Views are simply templates to present the data
Separate all JavaScript code into separate files (SOLID principles)
While in the AngularJS world I can see this working, I have recently run into an enterprise-level project where Knockout was brought into the mix a bit late in the MVC3 development process.
As such, the view had DTO/ViewModel data AND also contains Knockout data-bound controls, populated through RESTful requests, and JavaScript code is mixed into the Razor's *.cshtml code.
A new feature was required that presented data in a list. I added a new data construct to the model data, thinking that this was the data transmitted in the response to the RESTful request. Turns out it was not, but available on the MVC view as #model data. So on the view we now have a RESTful response, as well as MVC model (view model) data.
It didn't make sense to then JSON convert that data, then perform Knockout data binding, when I could simply use Razor syntax to do the same (round-about way of getting the same result).
This brings me to a related issue of using MVC model data in JS frameworks, and how to keep proper separation of concerns - not mixing your JS code in your view.
In moving forward, I don't like mixing the two methods of data access.
Specifically:
I would like to know if this is common practice - if so, because it was not properly planned out, or if there are other reasons to really mix the two.
Thanks.
It didn't make sense to then JSON convert that data, then perform Knockout data binding, when I could simply use Razor syntax to do the same (round-about way of getting the same result).
That sentence stands out to me because if you can simply use Razor syntax to fulfill your project requirements, then why do you even need Knockout? Knockout, like Angular, provides rich functionality through two-way data-binding and can make a site interactive without having to do any page reloads. If you just need to display static (or rather, non-interactive data), then a Javascript data-binding framework isn't really necessary - especially when you can just strongly type it out in your Razor view.
In answer to your question, I don't think that it is common practice to mix the two methods of data access - at least not on purpose. I feel the same way as you in that regard - I'd prefer only one method of data access and view rendering to reduce code clutter.
I'm considering switching to Ember.js for one of my Sinatra applications. Our current setup is using server-side Handlebars rendering along with RESTful routes for CRUD operation and Websockets for push notifications.
My main concern, however, is duplication of model code.
Ember Data is a library for loading models from a persistence layer (such as a JSON API), updating those models, then saving the changes. It provides many of the facilities you'd find in server-side ORMs like ActiveRecord, but is designed specifically for the unique environment of JavaScript in the browser.
From what I understand, to use Ember.js, I need to define my models in Javascript, thus duplicating a lot of the Mongo models that we already have server-side. Is this correct? How is it possible to mitigate code duplication in models when using Ember.js in combination with a Ruby backend?
You will probably want to split up some of the tasks between being done on the client side and being done server side.
The models themselves will be duplicated since it makes it easier to work with Ember if you have Ember Data models. Though, you could build your own models on the fly and just have api calls for everything (probably not advised). You would do that by doing the api calls within the model hook of the route.
Once you have Ember Data models setup though, you could keep your logic fairly simple and have the server to more complicated tasks. But this largely depends on application specific needs.
Until now I was mainly using Struts 2, Spring, JQuery technology stack for building web applications. The point is, that mentioned stack uses server side MVC pattern. The main role of web browsers was limited to a request/response cycle (+ client side validation). Data retrieval, business logic, wiring and validation were mainly responsibilities of the server side.
I have few questions regarding AngularJS framework that were inspired by following quotes I've read:
From the AngularJS tutorial:
For Angular apps, we encourage the use of the Model-View-Controller
(MVC) design pattern to decouple the code and to separate concerns.
From the Wikipedia Model–view–controller:
Model–View–Controller (MVC) is an architecture that separates the
representation of information from the user's interaction with
it. The model consists of application data and business rules,
and the controller mediates input, converting it to commands for the
model or view
AngularJS uses client side MVC pattern. So I guess there is no other option then to include validation logic also to the client side in some way?
What would be the best way to write a robust AngularJS application? MVC on client side and some kind of MC (model, controller) on server side?
Does that mean, that MODEL and CONTROLLER are in one way duplicated (client/server)?
I know my question is somehow weird, but I think the reason is, that I am somehow acustomed to traditional server side MVC pattern. I am sure there is someone, that have already done same transition.
Not at all a weird question - I've been trying to sell Angular to a lot of java developers and they ask this. I asked it myself when I was learning (I'm still learning, btw)
If you take a 'conventional' java webapp as you've described and Angular-ize it, you've got to first take your server and make it a RESTful API. Remove the JSPs, etc. This is actually the hard part, IMO, of writing an Angular app - getting the REST API right. The key for me to deciding what logic needed to go into the server was thinking of it as a pure api and forgetting for the moment that it will have a front end.
That question really helped me - if someone tries to save a given resource and that resource doesn't have valid data there's no front end to tell them - they're hitting the API directly so the API needs to reject it. So, the back end is responsible for the deep validation. This applies to your business logic as well. Assume someone is using just the API and it will become clear what your server needs to do.
The server needs also to vend data in (probably) json format (I use Spring MVC + Jackson), so it's responsible for exposing the model to Angular, and communication with the database.
So what's the MVC then on the Angular side?
Model: The data that comes from the REST API. If the API is vending JSON, then these objects will already be 1st class javascript objects.
View: HTML, and directives when you need to manipulate the DOM
Controller: (and custom services that you've factored out of your controllers..)
Queries the REST API and puts what's necessary for the View on the $scope
Provides callbacks for directives to respond to events that might then require calls back to the server.
Validation: usually via a callback to a directive. Will likely overlap some of the validation you've already put in the server, but you don't want your user to wait for the server to validate everything - the client should know something about the validation to give the user immediate feedback.
Business logic: Pretty much the same story as validation.
But why the duplication of logic in the client and in the server? Mostly because you're not writing one app, you're writing two independent things:
a REST API that needs to be robust and usable without a front end
a GUI that needs to give immediate feedback to a user and not necessarily wait for a server.
So, short answer - get the REST API right by forgetting that there will be a UI, and what goes into Angular will be much clearer.
I think the term "business logic" is a bit of a misnomer here. The "business" of a clientside app is the business of handling the user interface. It's not going to be things like security rules and proprietary logic or other sensitive intellectual property.
So in Angular the division is (generally):
Controller (controller): for manipulating the data (scope) behind your UI.
Directives : for setting up the DOM to communicate with the controller via scope, and for manipulating the DOM.
Templates (view): To assign directives to elements of the DOM.
Scope (model or viewmodel): for carrying data between all pieces of the system.
Services : Injectable, reusable bits of code. Usually for dependencies like handling Ajax, cookies, or other I/O.
It's really almost MVVM and not MVC.
As for your "business" logic or rules... anything requiring security must always be secured at the server level.
It's important to understand that in some versions of the MVC pattern, the data as well as the logic that manipulates the data both reside in the "model" layer (with the "controller" layer doing nothing but binding). In AngularJS, however, the data ($scope) alone resides in the "model" layer, while the logic that manipulates the data ($scope) resides in the "controller" layer.
I love what #Roy TrueLove says. But let me say that this is the ultimate way of using angularjs. Of course, you have to learn to do your applications this way, if you want to get the most benefit of angular. I pray to be there some day.
In the meanwhile, during your learning, and during your transition to fully using angularjs as your client side main way of doing things, you can start using it for some small mission here and there, and gradually get accustomed to it and to its way of thinking.
I encourage to gradually embracing it and to go slowly slowly, but surely, I guaranty, sure.
Angularjs is designed to serve this approach, as it can work on the smallest task as good as it can do the biggest one. For example, this first time I used angular was just to show names while the user types ids.
I agree with the answers here. Some more comments. When you write an applicacion, you first need to concentrate on the problem domain. And create a software model of some real business. For example, if your problem domain is a shopping, some requirements that you need to model might include:
The credit card should be valid.
If you pay with a credit card of brand X, you will receive a 10% of discount.
The shop cart should contain at least one item to perform the checkout
The items must have stock before allow users to add them to the shop cart
The implementation of these requirements will model your problem domain, this is your business logic.
Angular is a frontend framework and toolkit. It is a web frontend. If you implement this in a web frontend, you will miss the oportunity to reuse your model from other frontend or interface, like a mobile or a desktop application.
So, ideally, your business logic implementation needs to be decoupled from any user interface framework and decoupled from any persistent framework also. Then, you will have your interface objects that will deal with user interface problems and will comunicate with your business logic objects. This can be a Spring MVC controller, and/or an Angular controller or service.
There is a sample application you can take a look at, that follow the principles mentioned here.
I seems to be having this question as well, as some organizations just craze for new technologies - "I want cloud...wait, I want lightweight", its hard to justify whether it deserve for the switch to a lighther framework.
I develop webapplications using Spring/JBoss seam/JSF and on MVC framework all the time. Most of the time java scripts will reside for the presentation layer validations and the main action classes/entities and business logic will reside in Java code. After some basic hands-on on Angular, I started to get what they meant by MVC as they abstracted another level on the presentation layer, where we can have our own views and controllers on the front end. To answer your question, just like everyone's comment the best way is to lay it on the presentation layer.
As for security point of view, I believe heavy or sensitive business rules should reside on the server side as we do not want to expose it to the world. If the business logic is developed poorly, one can easily find the weakness on our code and exploit it.
Here's my thought for framework like Angular is like a small shop/SOHO handling customer, and they have a few people and really efficient and fast.They cater well for customers facing business and delivery/receive goods efficiently(REST, JSON). They do have designated roles and tasks, but some worker perform more than a tasks. The shop also vulnerable to thief or robbers as usually they don't emphasize heavy security.
As for server side framework like Spring/Struts 2, imagine a modern corporation(CMM Level 5) with different level of management and capable of handling bigger business(batch jobs, web services, enterprise bus). They do handle customer, but not directly, often go through brokers or even retail shops. Security wise a corporation is more robust, and often securities on the front door, or important information are protected in a safe(encryption/sign-on).
My approach is always the bottom-up approach. Starting from the Database Design, with properly constructed / related tables, stored procedures when needed, then add the Entity Framework to the solution or use ADO.Net if EF is not an option. Then develop the Business Logic, and the Models to get the data in and out the database.
With the Models established, we can now go two routes: Developing MVC Controller, and / or developing WebAPI controller. Both controllers can have access to the Models, it's just a matter of instantiating the classes and invoking the methods.
You now have the option of setting up MVC Views that are controlled by the MVC controller, or, entirely separate set of HTML pages or SPA (Single-Page Application hosted on NodeJS).
With the entirely separate set of HTML page, you will need to use WebAPI controllers, with Get, Post, Put, and Delete methods, and be sure to include token back and forth to identify your client, and enable CORS (for Cross Origin Request)
With MVC Views, you can identify your clients using the controller attributes, and / or sessions and no need to worry about CORS, and, you can even make your Views Strongly-Typed if needed. Unfortunately if you have a set of UI developers they will have to work on the same MVC solution.
In both cases, you can use AngularJS to transport data back and forth from / to the controllers.
IMHO the concept of AngularJS controller is not the same with C# MVC or C# WebAPI controller. AngularJS controller house all the javascript logic as well as the calls to endpoints via the "ApiFactory", whereas C# controllers are nothing but Endpoints in the server side that accept and respond to UI requests.
I am just starting to look at MVC structure, first i looked at how backbone.js worked, and now I have just completed rails for zombies, by Code School. I know that I haven't delved too far into any of this, but I had a question to begin with.
Can you use these libraries together?
I have learned how to create models, views, etc in both, but when creating a real application do you use both backbone and rails?
If so...
When do you use a backbone.js model vs. a rails model?
Maybe I am just getting ahead of myself and need to keep practicing and doing tutorials but I couldn't seem to find anything directly on this.
Thanks!
Before anything else I'd suggest taking a look at thoughtbot's Backbone.js on Rails book, which is a great starting point, although aimed at an intermediate to advanced audience. I bought this book having already worked with rails but as a total backbone.js beginner and it has served me very well.
Beyond that, there are some fundamental issues with combining these frameworks which go beyond the details covered in this book and other books. Below are some things I'd suggest you think about, from my own experiences pairing RoR and backbone.js. This is a long answer and strays a bit from the specifics of your question, but I hope it might help you out in the "big picture" sense of understanding the problem you're facing.
Rails: Web Framework vs API
The first thing you confront when using backbone.js on top of a rails application is what to do about views, but this is really just the surface of a much deeper issue. The problem goes to the very heart of what it means to create a RESTful web service.
Rails is set up out of the box to encourage its users to create RESTful services, by structuring routing in terms of a set of resources accessed at uniform URIs (defined in your routes.rb file) through standard HTTP actions. So if you have a Post model, you can:
Get all posts by sending GET request to /posts
Create a new post by sending a GET request to /posts/new, filling out the form and sending it (a POST request) to /posts
Update a post with id 123 by sending a GET request to /posts/123/edit, filling out the form and sending it (a PUT request) to posts/123
Destroy a post with id 123 by sending a DELETE request to /posts/123
The key thing to remember about this aspect of Rails is that it is fundamentally stateless: regardless of what I was doing previously, I can create a new Post simply by sending a POST request with a valid form data to the correct URI, say /posts. Of course there are caveats: I may need to be logged in (have a session cookie identifying me), but in essence Rails doesn't really care what I was doing before I sent that request. I could follow it up by updating another post, or by sending a valid action to whatever other resources are made available to me.
This aspect of how Rails is designed makes it relatively easy to turn a (Javascript-light) Rails web application into an API: the resources will be similar or the same, the web framework returning HTML pages while the API (typically) returns data in JSON or XML format.
Backbone.js: A new stateful layer
Backbone is also based on RESTful resources. Whenever you create, update or destroy a backbone.js model, you do so via the standard HTTP actions sent to URIs which assume a RESTful architecture of the kind described above. This makes it ideal for integrating with RESTful services like RoR.
But there is a subtle point to be stressed here: backbone.js integrates seamlessly with Rails as an API. That is to say, if you strip away the HTML views and just use Rails for serving RESTful resources, integrating with the database, performing session management, etc., then it integrates very nicely with the structure that backbone.js provides for client-side code. Many people argue that there's nothing wrong with using rails this way, and I think in many ways they are right.
The complications arise though from the issue of what to do with that other part of Rails that we've just thrown away: the views and what they represent.
Stateful humans, stateless machines
This is actually more important than it may initially seem. HTML views represent the stateless interface that humans use for accessing the RESTful resources your service provides. Doing away with them leaves you with two access points:
For humans: a rich, client-side interface provided by the backbone.js layer (stateful)
For machines: a resource-oriented RESTful API provided by the rails layer (stateless)
Notice that there is no longer a stateless (RESTful) interface for humans. In contrast, in a traditional rails app with an API, we had something closer to this:
HTML resources for humans (stateless)
JSON/XML resources (API) for machines (stateless)
The latter two interfaces for accessing resources are much closer in nature to each other than the previous two. Just think for example of rails' respond_with, which takes advantage of the similarities to wrap various RESTful responders in a unified method.
Working together
This might all seem very abstract and beside the point, I know. To try to make it more concrete, consider the following problem, which gets back to your question about getting rails and backbone.js to work together. In this problem, you want to:
Create a web service with a rich client-side experience using backbone.js, with rails as the back end serving resources in JSON format.
Use pushState to give each page in the app a URL (e.g. /posts/123) which can be accessed directly (by entering it into the browser bar).
For each of these URLs, also serve an HTML page for clients without javascript.
These are not unusual demands for a modern web service, but they create a complex challenge. To make a long story short, you now have to create two "human-oriented" layers:
Stateful client-side interface (backbone.js templates and views)
Stateless HTML resources (Rails HTML views)
The complexity of actually doing this leads many nowadays to abandon the latter of these two and just offer a rich client-side interface. What you decide to do depends on your goals and what you want to achieve, but it's worth thinking about this problem carefully.
As another possible reference for doing that, I'd suggest having a look at O'Reilly's RESTful Web Services. It might seem odd to be recommending a book on REST in a question about Rails and Backbone.js, but actually I think this is the key piece that fits these very different frameworks together, and understanding it more fully will help you take advantage of the strengths of both.
Yes, you can use both side by side. Backbone is for storing and manipulating data within the client browser. It generally needs a server to talk to and fetch the data from. This is where Rails comes in. You can have a web application without heavy client-side code. Backbone is for building out sites that feel more like apps--think of Gmail or Pandora.
I advise just learning Rails first. Once you can get static pages loading and styled as you wish, then understanding Backbone's place will make more sense
I've used rails as a backend server to serve a fairly large website, which included a few one-page apps (built in backbone).
I'd suggest the backbone-on-rails gem. The idea is that your rails server will serve up the backbone app as a script tag in one of your views. You keep your backbone app itself in the rails app/assets folder.
Backbone understands rails routing conventions, and you just need to give it a path to a json api that rails can almost generate for you with rails generate resource.
Other than the syncing between the models, your backbone apps and rails apps are fairly separate. Backbone and Rails don't have quite the same MVC model, but getting them to cooperate is pretty easy.
I know that MVC is highly acclaimed for PHP applications, but I am not sure at all that it fits in JavaScript. If you think otherwise, then please explain how and where you handle common scenarios like AJAX requests, data saving (offline storage), presentation, how do you handle controller logic (do you have a front controller?), and so forth.
What about Model-View-Presentation?
I am using ExtJS and using the server only for permanent data storage.
If you're planning on coding your UI purely with JavaScript, you could think your PHP end of things as more of a web service or an API.
Basically your View would be the Ext JS stuff you write in JS. To work with your data, the Ext frontend would perform requests to your "service". Basically you would have a sort of model-controller architecture on your server, where the job of the controller would be to process requests and output JSON (for consumption by your Ext frontend)
Essentially, the "view" in your backend would simply be output from json_encode, which is then consumed by your actual Ext based view.
In JS, you can have controllers depending on what sort of stuff you're doing. If you're just displaying data from the server, you may not require much separate logic. If you're doing some more complex processing, it may be useful to separate the code into a separate controller and view.
It's mostly up to how much you want to separate the logic.
When writing almost complete javascript applications you can think of MVC as:
View: The DOM
Controller: Your JavaScript
Model: Combination of JavaScript Ajax Calls and their PHP (or whatever) backend counterparts
PureMVC is an extremely cool MVC framework. You should check it out.
I'm using the same architecture: predominantly ExtJS on top of a PHP back-end.
My solution:
Strict JSON-RPC communication with the server. The server-side API is clean enough that it's also our third-party interfacing API. Forcing the API to be the same one that third-party interfaces use makes you keep the server-side code clean and minimal, which is good for security and performance.
Heavily componentized architecture, split into modules that group components (Ext.Panel derivatives usually). Each component knows how to request its initial configuration and data via JSON-RPC calls, render itself, and save its state if necessary. I try to keep the communication between components clean and documented.
On-demand architecture, loading in additional components via javascript files as needed. The entire code is designed to be initialized via callbacks, so that components can load their dependancies from the server and render only an empty placeholder before they initialize themselves.
Individual components may employ an MVC pattern, where it makes sense. Ext tends to encourage MVC anyway, separating data out into stores and having a separate rendering infrastructure (although it does blend controller logic with the rendered components).
I'm not sure I understand where you are going with your question, but I'll give it a shot.
MVC is an architectural pattern which in its essence means keeping the data model, the controller and the UI loosely coupled as much as possible.
You are trying to boil it down to the technological level, and it's not really making any sense. You can do proper MVC with a good framework. Just to make things clear, plain-vanilla PHP does not give you good MVC support. A good framework, such as CakePHP or CodeIgniter - will.
JS is just a nice way to enrich the client-side experience. Meaning that unless you are doing server-side JS, the only place you will have JS is in the view itself. AJAX requests have nothing to do with MVC, per-se. Neither does data persistence. Unless you are implementing your own controller (and you better have a damn good reason to do so yourself), you shouldn't be worried about its internal logic.
Bottom line, if you want to do proper MVC, use a proper framework, and all will fall into place.