Recently I faced an ugly problem in my project when I begin the design of a complex View which have to handle with many data sources. The purpose of the View is to show data related to the profile of a Customer but this profile it's made of:Basic Info, Project involved, financial data and contact info. All that data must be grouped in the same View and must be updatable. Additionally to this, in the right pane of the view, there are a few of widgets pointing to other sources not related with the customer information.
My approach to solve this was:
Create an hybrid model which it's a mixed of various models like: personalInfoModel, cutomerProjectModel, financialInfoModel, and contactInfoModel. By the way, I am using Microsoft entity framework, so every model here match with an entity one to one.
With this hybrid model, I make the connection to the main View (let's say CustomerView) so in the first line of the view code you can see something like:
<%# Page ..... Inherits="...MyProject.Models.hybridCustomerModel"
Inside the main view I use:
<% Html.RenderPartial("UC_BasicInfo"); %>
<% Html.RenderPartial("UC_ProjectInfo"); %>
<% Html.RenderPartial("UC_FinancialInfo"); %>
<% Html.RenderPartial("UC_ContactInfo"); %>
This is because I want to simplify things a bit by mean of user controls for rendering of the main View.
Every User Control (¨*.ascx), is pointing to the hybrid model so I can make the binding in the controls of the forms without problem.
In the controller the things looks a little disordered. For every *.ascx there is an action's Method handling the "post request". But the initial loading or Get request, is made inside the only action method which match with the View Name: CustomerView.
For the purpose of usability and responsiveness I use jquery to make the post request.
But the problem is that I need to make a lot of work Mapping the hybrid model with the plain model involved in the Post Request, because the DATA layer receives only the model which maps with every entity created by the Model.
Finally, I am using: <% Html.RenderAction() %> for the Widgets at the right pane of the view in order to get data out of the hybrid model I am using.
I wanted to ask you if there is some different and better approach in this case?
I think there are a couple of approaches you could use to simplify this.
Firstly instead of the hybrid view, why not make up a view-model class. This will contain your hybrid data, but will be a pure poco class. Its much safer to bind to, as you control what fields are exposed.
Having a controller method for each ascx is not such a bad thing, but if you prefer one, and to wrap the page in one Form, you can either use button type="submit" (rather than input type=submit) or javascript to tell which button was pressed and which bit of the posted viewdata to map back to your EF classes.
Another approach, and given that you have already taken a dependency on javascript, this is the one I would favour:
I'd attempt to decouple the page into the independent partials, give each one a pair of controller methods (Get and Post) and assemble the page by requesting each partial with Ajax type calls. Your sticking point here will depend on whether an update in one cascades into others : if the interdependence is fixed and acyclic this will be pretty easy to resolve otherwise you might need to develop some sort of light messaging framework - or just allow some types of update to trigger a full page refresh.
Related
The following example uses an MVVM approach to update a property based on a picker selection:
https://github.com/xamarin/xamarin-forms-samples/blob/master/UserInterface/BindablePicker/BindablePicker/BindablePicker/SimpleColorPickerPageViewModel.cs
It uses OnPropertyChanged("SelectedColor"); when the selection changes to update another property.
I have two questions:
Firstly, is there any advantage of using this approach over the normal OnSelectedIndexChanged event in the xaml.cs?
Secondly how would i use this approach if i wanted to update a particular item for my custom object in my viewmodel. For example, if the selected item changed in the above example, store the value in another object in the view model?
It just seems long winded to the OnSelectedIndexChanged approach, but guessing there are advantages i'm unaware of?
basicaly i have a number of dropdowns on a page, and with each change, i want to update the object in my view model which will be sent back to the server with a rest service.
Picker.SelectedIndexChanged is not as straigthforward since you will still need to index the list and find which item and since it's not a command, you need to implement it in Code Behind.
You just said that you need to send rest http requests, so it means that your app is fairly complex so you will probably need ViewModels and to keep your code coherent, you should apply the same pattern to all pages.
For the sake of keeping things neat and tidy I always implement MVVM even if the Page logic is not very extensive.
MVVM also facilitates (a lot) unit testing your application.
But in the end, it's all about taste.
I am new to knockout.js. Few moments back I read the headline features of ko.
I could not understand is ko really MVVVM? Because all they talk about is data binding and the ease of it. But I am sure MVVM is more than data binding isn't it?
Yes, knockout.js does apply the MVVM pattern. It's explained in the documentation:
A model: your application’s stored data. This data represents objects and operations in your business domain (e.g., bank accounts that can perform money transfers) and is independent of any UI. When using KO, you will usually make Ajax calls to some server-side code to read and write this stored model data.
A view model: a pure-code representation of the data and operations on a UI. For example, if you’re implementing a list editor, your view model would be an object holding a list of items, and exposing methods to add and remove items.
Note that this is not the UI itself: it doesn’t have any concept of buttons or display styles. It’s not the persisted data model either - it holds the unsaved data the user is working with. When using KO, your view models are pure JavaScript objects that hold no knowledge of HTML. Keeping the view model abstract in this way lets it stay simple, so you can manage more sophisticated behaviors without getting lost.
A view: a visible, interactive UI representing the state of the view model. It displays information from the view model, sends commands to the view model (e.g., when the user clicks buttons), and updates whenever the state of the view model changes.
When using KO, your view is simply your HTML document with declarative bindings to link it to the view model. Alternatively, you can use templates that generate HTML using data from your view model.
In addition to the answer already provided, there are a few things to keep in mind -
MVVM
Knockout is MVVM because it supports a good separation of concerns. Unlike other JavaScript libraries, such as jQuery, it's goal is to not pollute the view with that which does not concern it.
The view model's purpose is important to understand. It does not attempt to manipulate the DOM because only logic required to serve up data to the view is placed inside of it.
The view's purpose is only to present (render) the data. No logic, validation, or other logic code goes here.
The model is the only place where Knockout can get a bit tricky. It is generally a good accepted practice to place a separate model in your project for Knockout to use, but many developers have found the ease of mixing the model into the view model. The reason for this is obvious (some models are very basic) but again this is only out of ease of implementation.
MVC vs MV*
Surely there are other answers on SO.com that attempt to answer what is MV*, but I wanted to throw my $0.02 in here - Other libraries or frameworks speak to the fact that they are MVC or MVP or MV(whatever) based but Knockout is the only one that I have found that practices what it preaches in this regard. If you have the time and desire look at the structure of other frameworks such as Angular or Ember and you will see there is a blurred line that exists, and more or less they are simply using an MVVM based pattern but calling it something different.
Well I guess it can, however I am working on a project where all styling and UI layout manipulation is done in the knockout js ViewModel file, which is not good practice.
In my current MVC2 project I implement my MVC by creating a "model" class that gathers data from the database and runs it through business logic, etc. Then I have a "Controller" that gets the processed data from the model and sets the values in a "ViewData" class. This "ViewData" class is a class of getters and setters. This ViewData is then passed to the view in the Controller like this : return View(myViewData);. Finally, in the View, I bring in the data stored in the ViewData by putting this line at the top of my aspx file.
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Core.UI.Web.ViewData.MyViewData>" %>
So, is this the way MVC3 is done? I have a guy on my dev team that is suggesting that the model should be sent, via the Controller, directly to the view like this: return View(myModel);. His reasoning is that this is MVC not M.V.VM.C.
I understand that ViewBag can be used but that just seems like a quick data container.
So, in other words. ViewData or no ViewData?
Thank you,
Aaron
There are certain situations where you might want a view model: to combine data from multiple models/sources, or for specific validation scenarios, etc., but, it's perfectly acceptable to have your view take a model without an intermediary view model, especially if the view model is just a class of getters and setters with no other functionality.
If you're not concerned about exposing methods/properties from your domain model (or if it doesn't apply), I would just pass the model straight to the controller.
In your instance ViewData is just a model - it is a ViewModel and is perfectly fine, and actually the recommended approach in general to use. The reason being you dont want for instance, a primary key from a customer model rendered in the case of a "create customer" function - as a customer id doesnt yet exist. However for editing a customer record, you surely need a key. So - if you use viewmodels in some cases and not in others, not you are inconsistent in your project.
'yes' you can - but I prefer consistency and using a view model gives you the consistency.
You can also use the model - and thats normally how the MVC demos are setup, but unfortunately like most demos, they don't give you what is architectually best, but what is best in whipping together a 5 minute application.
As other have said, although you can get by passing Models to your views, sooner rather than later you'll find yourself wanting to add properties for display purposes only that don't quite belong to the model (e.g. values depending on the current session rather than the model itself.) When you hit that point and it's usually pretty soon you'll be glad you used viewModels.
Technically speaking ASP.NET MVC is not even using MVC but rather Model2. Dino Esposito has a good article about this. Furthermore, on his book Microsoft .NET: Architecting Applications for the Enterprise he even goes as far as saying:
"It is a sharp and bold statement, but we have to make it: today classic MVC is gone. However, some of its variations are healthy and thrive. They are Model2 for the Web and MVP for both Web and Windows. In turn, and only more recently, MVP has undergone a facelift. In July 2006, Martin Fowler proposed to retire MVP entirely and replace it with two variations Passive View (PV) and Supervising Controller (SVC). “
I wrote a review of this chapter on my blog.
Hi
I've been building the backend of my application (using nHibernate for data access).
So far i've had some simple web-services for manipulating my data, but now I'm required to develop a web UI on for my application (using web forms).
I've been looking at some different web frameworks (webformsMVP, spring.net web), and also at some client-side JS frameworks (knockout, angular), and I can't really decide what would be the best for me, and how to integrate it all.
I was hoping to get some insight from you guys.
I think I would like for my general workflow to be something like this:
View is created, calls its presenter.
Presenter contacts business layer to retrieve information (which in turn contacts DAO etc.)
Presenter returns a view-model object, which the view displays.
User manipulates data (maybe using some AJAX to retrieve further needed information)
View sends a view-model of the manipulated data back to presenter
Presenter translates the view-model into a model entity and sends it to business layer
now here are the parts that I find tricky:
A. How to map between view-model and model entities
I think I should use the entitie's ID to retrieve the unchanged entity from the DAO (which actually stores it in nHibernate's 2nd level cache), and perform changes on it.
(another option is to store the entity i'm currently editing in the user's session. but i'm afraid that this kind of caching would create duplicity with nHibernate's cache.)
B. How to translate changes on the view-model into changes on model entities
I'd like to have some logic when changing model entity's properties.
For example, for moving an employee from one department to another, I don't want to allow this-
department1.Employees.Remove(employee);
department2.Employees.Add(employee);
but rather this:
employee.MoveToDepartment(department2);
I'm afraid this could get complicated when translating from a view-model into a model.
Any thoughts on the above two questions, and also about any client-side / server side frameworks would be appriciated.
P.S. some quick background on my app:
-one page of the web app displays the company's structure (departments, divisions etc.) as a tree, and allows the user to click and edit the different nodes, as well as drag-and-drop nodes to change their location.
-another page displays current stock status (for each warehouse- how many products it has, how many machines are currently operative in that warehouse etc.)
- (some more pages which basically display data and allow editing...)
thanks
Jhonny
You can check out Automapper for your entity mapping. Alternatively you can write your own entity mappers and entity updaters. You can then encapsulate the business logic like Move To Department in your entity classes.
Your approach sounds just fine, and I can recommend Webforms.MVP as that is a good framework for writing testable WebForms apps without rolling your own implementation.
Overview
I have a payment page where I allow the user to select a payment method, either credit card or check. I have a form for each of these payment methods. I did not want to create a separate page for each of these methods for UI purposes, so I use a [div] for each form and toggle their display with jQuery.
Problem
Each of the payment methods has its own set of validation rules. I want to be able to apply model validation to only the payment method that was selected and submitted by the user. In order to do validation, I am required to POST to the same controller action, so submitting to different actions is not an option.
Approaches
I have considered the following approaches:
Partial Validation based on incoming values, as described here: http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/. My issue with this approach is the security implication, and as this is a relatively small app, I don't have a separate domain layer as the author of the article suggests.
Create separate models for each payment method, and then overload the controller [HttpPost] action with a different model parameter. I tried this but the compiler complains that the action is ambiguous, even though I have something like this
[HttpPost]
public ActionResult Pay(CreditCardPaymentModel model) {...}
[HttpPost]
public ActionResult Pay(CheckPaymentModel model) {...}
Use separate controller actions to handle the individual form posts and use TempData to set the validation messages and redirect back to the form page to display the messages. I really don't like this option as it feels clunky, and I don't like using TempData for anything other than simple messages.
I would welcome any suggestions on the best way to handle such a situation cleanly and efficiently.
I would go with option 2, as it gives you a nice, clean separation between payment models and concrete model classes (I always go for strongly typed solutions).
Option 2 will also be easy to unit test...
I'd go for the strategy 3.
When you toggle form views with jQuery you can also replace the post url of the form. This way it can easily be handled by different controller methods each with their own validation logic.
One other option (not the one I like) is to create a merged model for both payment option. Upon instantiation of that model you can probably easily distinguish what form was active. Or you can also set some hidden value with jQuery to indicate the active form view.
P.S. With #2 it is difficult to tell which model instantiation will work out until the framework attempts to instantiate one and if it fails another. This is not quite straightforward and the framework was not built to be that intelligent and bring some initiative into the process.