I am planning to use knockout.js and MVVM pattern on the client side for a Single Page application. So Models, ViewModels would be defined on the client side. I am confused about how we have to structure on the server side.
Now, would controllers just return domain model itself ? Would all the mapping from domain model to ViewModel happen only on the client side ?
In my solution, there is wide gap between the Domain model and the ViewModel. So the above approach would result in a lot of data being returned to client side unnecessarily. Though it seems like overkill, I am thinking about repeating ViewModel and InputViewModel definitions (former represents data rendered, latter represents data to be posted back to controller actions) on server side and also having a mapping layer (based on automapper) to map Domain models to ViewModels on the server side. Does this make sense ? Or is there a better approach ?
I would suggest that you work out what data your view models actually need, then have the controllers build up a server-side view model that contains that data and send it to the client in a JSON format.
This way you are not sending unnecessary data over to the client (or back), you are still able to do much of the heavy lifting on the server and the knockout view models can do what they are meant for: presenting the data to be used by the view.
What you described in point 2 is actually the solution I use the most and it makes sense to me:
I use Automapper on the server side to map between Domain models and ViewModels (.Net objects) that are View specific and contain only the data the View needs.
The Controller Action that is responsible for loading the View the first time, will databind the View to the ViewModel, so that the page is initialized quickly without the need to make an Ajax call.
In the View itself I create the knockout viewmodel, assigning any initial values (if needed) by Json encoding the bounded ViewModel (for example using Asp.Net MVC i would do something like
var boundedViewModel = #Html.Raw(Json.Encode(Model));
That is exactly how I would approach this problem. If this were a straight MVC app, you would still be creating viewmodels.
Sometimes for complicated data sets, I can see a use case for using something like Knockback, which takes the rich data model of backbone.js and combines it with knockout.js
http://kmalakoff.github.com/knockback/
Related
Is it a good practice to use Spring Controller class(with #ModelAttribute) and the jsp to prepare model at the same time or the model has to be prepared only by Spring and the view from the jsp?
The idea comes from this topic . I have a Controller class:
#RequestMapping(value = {"", "/"}, method = RequestMethod.GET, params = "mode=create")
public ModelAndView showCreatePage(#ModelAttribute("createForm") ApplicationCreateForm form)
{
return customMethod("some string");
}
and in my jsp I have:
<jsp:useBean id="createForm" scope="request" class="com.example.ApplicationCreateForm"/>
I do not need to populate the form with the information to be present to the user all fields are empty.
So from what I uderstand I have been declared ApplicationCreateForm bean twice, with the same scope - request.
Is it a good design practice to use both at the same time? Is there a reason for that? Does the second declaration(in jsp) give me more power, for example to override the model or it is complete unnecessary? Does the second declaration overrides the first one when both are present?
There are many things wrong with this implementation.
Is it MVC?
If JSP know about Model, why do we need controller. Lets remove the routing engine and use JSP directly to consume Model. But then the application will be monolithic. I believe you do not want that. We have two major flavours of MVC. In both, controller is the front facing object. It receives the command, interprets it, works with data layer and gets Model. If required the Model gets converted into a viewModel and then this object is passed to the view.
Why viewModel?
Say we are implementing paging on screen. We are showing list of persons. Person is your model here but your view also need to know page number, page size etc. Your model thus may not fit directly in this case.
Say we need data from multiple tables to shown on screen. This data is related in some way. Now will you pass separate model objects to view and let it do all the business logic? Ideally no.
Should not the design support DTO or ViewModel or Commands and Queries?
We want our application to be designed properly. As stated above we need to send data to view or clients (REST) after processing. Processed data may not map to you domain until unless we are just creating a CRUD stuff. What if you want to implement CQS or CQRS?
Where is separation, where is SOLID?
If my view is performing business logic then where is 'S'? If view knows about model and need to be changed in slightest of changes in model then where is 'O'?What if I want to separate queries from command (CQS) and scale the two things separately?
To conclude I would say, yes you can do this but it is not good if you are developing a decent size application or you think it will eventually be one. I have seen people using model entities starting from ORM, to controller to view. It will work but the question is do you want a monolithic and tightly coupled application. As per my experience the presentation logic (view) has very different logic and need of data in comparison of controller and same goes for your data access layer.
I think you should prepare your model fully in spring controller. Then view should be as passive as possible, ie. only showing model attributes received from controller while having no further knowledge about application logic. This approach gives you clean separation of concerns and you view is as independent as possible and can be easily switched for different view technology - eg. thymeleaf or freemarker templates. The whole idea of MVC is to separate presentation layer and by leaking business logic to view you create unnecessary dependencies.
Your view should be as simple as possible, as the logic leaked to view makes it very hard to test and reuse. On the other hand, if your logic is nicely separated, you can test it easily and reuse it easily. Ideally, business logic should be completly independent on web environment.
By defining you are creating tight coupling between your view and class com.example.ApplicationCreateForm, using spring mvc you achive loose coupling between your controllers, view and model it might happen that you change you model name but you still have same properties in it which might be enough for view, in above case you will need to update your view but it won't be required in case you are using Spring MVC.
Since spring comes with the concept of making things loosely coupled to make your code more testable, you should always keep in mind that separation of concern is your priority. So it is always the best practice to prepare your model fully in Controller, not in views.
Keep thing simple , make your controller responsible for preparing your model, and keep your views to display the model only.
So, a big NO to your question. The second declaration isn't going to make you powerful, rather help you to be tied up.
I'm writing an application which uses ASP.NET MVC with JSON.NET as the server, sending JSON to the client which is read by Knockout and then displayed with data-bindings. This is all working wonderfully, except for one problem:
I have a class Customer which is used to generate a ReviewAuthorViewModel class - the latter is meant specifically for JSON serialization and removes unnecessary fields, circular references, etc. On the client, I want to render a link to the Customer's profile page, with the URL coming from a defined MVC route "user/{username}". Because I'm sending this via JSON, I don't have a .cshtml page in which I can call Url.Action.
The question is: For an arbitrary object, how do I most efficiently/elegantly get a URL for an action with some data, without a .cshtml view?
I'd prefer a solution that doesn't require extra code in each action, but that may be the only choice apart from recreating the routing tables client-side in JavaScript. Below are the things I've already tried, and what was unsatisfactory with each.
Solution Attempt 1
Call the UrlHelper.Action method in the ReviewAuthorViewModel class. However, the UrlHelper requires a request context. For the sake of separation of concerns, I don't want my view model to have a dependency on System.Web.Routing, nor do I want it to need a request context to function.
Solution Attempt 2
Create a class RouteInformation with members Controller, Action, and Data, and an interface IUrlViewModel with two properties, a get of type RouteInformation and a get/set string named Url. The view models needing links then implement this interface, and controllers look for view models of type IUrlViewModel and run UrlHelper.Action with the information from the view model's RouteInformation instance, storing the result in the Url property.
This one works but without reflection I don't know how to find view models implementing IUrlViewModel within other view models, and it feels very kludgy.
Solution Attempt 1 is the OK solution. In asp.net-mvc, view models are part of presentation layer, designed specifically for use with views. You should not worry about having view model depend on asp.net specific things. In fact, they should be coupled, as they should be designed to maximize simplicity of view generation and data exchange between web server and web client. And it's good solution to create separate view model and not use Customer class directly for clients. It wouldn't have been OK if Customer was dependent on Routing.
In fact, you could set that property in controller -
[HttpGet]
public ActionResult Get()
{
var viewModel = new ReviewAuthorViewModel();
viewModel.ProfilePageUrl = Url.Action("Index", "Profile");
// return viewModel;
}
Data binding establishes a direct coupling between the view and the model, thereby bypassing the controller. Fundamentally this breaks with the Model-View Controller architectural pattern, am I right in thinking this? Does this make data binding a "bad thing"?
Edit: As example, angular claims to be a MVC framework, yet one of its main features is data binding.
In my opinion Data Binding can be a valid implementation of the MVC Pattern since the data binding mechanism itself acts as the controller in that case.
For example in the mentioned angular it seems like the $watch function is a shortcut to implement features that are typical Controller responsibilities and features in an MVC-style way.
So in my opinion data binding is an evolution step that implements best practices learned by implementing classic MVC controllers.
UPDATE
But in original pattern sense I would characterize data binding more like MVP or Passive View.
But the differences aren't that sharp in my opinion since it always also depends on your UI technology.
Not necessarily, since you don't have to bind your Model objects to the view.
What I usually do is create simple DTOs (or Presentation Objects) that contain only the data I want to display, and that's what the View layer displays.
In that case, the Controller retains its function as a translator between actions performed on the DTOs and actions on the underlying Model entities.
Actually, when your data is abstracted properly, the act of pushing the content of your models to your UI is a repetitive task that normally lead to some kind of "helpers".
Let's say to push a list of items to a combobox. This is not necessarily part of the controller as you may want to share such functionality. Also pushing the value of the control (to keep it simple, let's say the text of a textbox) is repetitive and bi-directional.
Also here you repeat your self (think of DRY) and do the same thing over and
over again.
That's exactly the point where databinding comes into play. This can take over the tasks that anyway are identical for simple controls (checkbox, textbox, combobox). For grid control and the like it may be specific.
Have a look at mvc & databinding: what's the best approach?. Here I discuss what could be the optimum when using databinding in combination with MVC.
Data Binding does not directly couple the view and model, so it is not a Bad ThingĀ®. It is an integral feature of the MVC architecture, which the GoF Design Patterns book describes succinctly in chapter 1.
MVC decouples views and models by establishing a subscribe/notify protocol between them. A view must ensure that its appearance reflects the state of the model. Whenever the model's data changes, the model notifies views that depend on it. In response, each view gets an opportunity to update itself. This approach lets you attach multiple views to a model to provide different presentations. You can also create new views for a model without rewriting it.
It's a common misconception that MVC is a layered (3-tier) architecture. It is not. The model updates the view(s) directly. But this does not mean the two are coupled! A publish/subscribe design keeps the model and view decoupled.
This more general design is described by the Observer design pattern.
I am learning Zend Framework and Doctrine.
I am wondering what is the best practice to connect forms to models and vice versa.
In some cases it is handy to load data from model in form class. Lets say a very unique class which use many models.
In other cases it is convenient to have methods in model class which prepares data for forms. Lets say it could have a method which returns an array prepared for select-options element, so this method will be useful for many forms.
I would like to have consistency and always keep this logic in one layer.
I think controller is not the right place because I want to keep it clear and simple.
What is your practice to achieve this goal (connect models to forms) ?
-
I am coming into conclusion that I should prepare my models for all my needs. If I have to deal with many models I will have a service layer (is it the right term?) which will connect those models. So the model or the service will have methods to hydrate data for forms. And it will be able to accept data from form values.
I think the controller is the best place for connecting models and forms. If you want to prevent a lot of code for populating the form create a populate method on the form that accepts a model.
If you let the models and forms communicate directly it will become very confusing what will happen at a particular time. I would create convenience methods like the populate method to keep things short, but all actions should be initiated from the controller to keep things central and prevent "magic behaviour".
Just my 2 cents..
Hey guys - here's a question on Zend Framework or better on MVC in general:
I am asking myself for a quiet a long time now, if it is a good idea to push business objects (User, Team, etc.) to my views or if it would be better just to push dump data containers such as arrays to the view for rendering.
When pushing business objects to my view I have a much tighter coupling between the views and my domain model, however, the view could easily do things like foreach($this->team->getUsers() as $user) { ... } which I personally find very handy.
Providing domain model data in dumb arrays to me looks more robust and flexbile but with the costs of that the view cannot operate on real objects and therefore cannot access related data using object's method.
How do you guys handle that?
Thanks much,
Michael
It's better to make your View access a Domain Model object in an object-oriented manner, instead of using the Controller to convert Model data into plain scalars and arrays.
This helps to keep the Controller from growing too fat. See the Anemic Domain Model anti-pattern. The Controller only needs to know what Model to instantiate, passes the request inputs to that Model, and then injects the Model into the View script and renders. Keep in mind that a Domain Model is not a data-access class.
You can also write View Helpers to encapsulate a generic rendering of a Domain Model object, so you can re-use it in multiple View scripts.
Your View should accesses the Domain Model only in a read-only manner. View scripts should not try to effect changes to the Domain Model.
You can also design your Domain Model to implement ArrayObject or other SPL type(s), as needed to make OO usage easy in the View script.
It's true, a large driving motivation of MVC and OO design in general is decoupling. We want to allow each layer to remain unchanged as the other layer(s) are modified. Only through their public APIs do the layers interact.
The ViewModel is one solution to abstract the Model so that the View doesn't need to change. The one I tend to use is Domain Model, which abstracts the details of table design, etc. and supplies an API that is more focused on the business rather than the data access. So if your underlying tables change, the View doesn't have to know about it.
I would expect that if there's a change to the Domain Model, for instance it needs to supply a new type of attribute, then it's likely that your View is changing anyway, to show that new attribute in the UI.
Which technique you choose to decouple one layer from the others depends on what types of changes you expect to be most frequent, and whether these changes will be truly independent changes, or if they will require changes to multiple layers anyway.
The "standard" approach would be to completely prepare the model in the controller (e.g. fetch all teams, including users) and then send that to the View for presentation, but you are not bound by that. The data structures can be whatever you want it to be: Array, ArrayObject or custom Classes - anything you deem appropriate.
I dont use Zend framework, so this is in repsonse to the general MVC Have a look at the ViewModel pattern.
http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspx
I'm comming from a .Net MVC point of view but I believe the concepts will the same.
I will do all my view rendering in the controller bascially like below
model only output dataset/objects (this should contain the most code)
controller assign view and add necessary HTML and make use of models
view only contains placeholder and other presentation stuff and maybe ajax call
So my team can work on each part without interrupting each other, this also add some information security to the project i.e no one can retrieve all the working code they only communicate by variables/object spec.