i'm facing the problem of the view showing data that's not in the model, and the model containing data that isn't in the view.
Imagine the data model has a birth date field:
DateTime: BirthDate;
And the view lets the user enter a birth date:
Birth Date: 11/28/1973
And that date goes into the model via the controller and all is right with the world.
But the way that text got into the TextBox was not at once, first the user types a "1":
Birth Date: 1
i cannot parse a "1" as any sort of valid date. The controller can react to this turn of events, e.g.:
- it can leave the existing BirthDate in the model alone
- it can set it to some form of "empty"
But now we have a problem because the view shows:
- "1"
but the model contains
- 11/28/1973
We have a disconnect between what the model contains and what the view shows.
The view is supposed to represent what is in the model, but it doesn't. Instead it is showing text that it stored in a TextBox.Text property. How do i reconcile the disconnect between the view showing what the model contains, and the view showing what it actually needs to?
i need to store this value somewhere. i can't leave the "1" sitting in the TextBox's Text
property, and it can't be stored in the model. What to do?
What if the user made a typo:
Birth Date: z
The view shows:
- "z"
but the model contains
- 11/28/1973
Things get even more complicated when the view is nothing like the data model at all:
Birth Date: 6 days ago
My controller can parse this string and convert it into a date, e.g. 3/11/2010. The controller stores the date 3/11/2010 in the model. But now we have a discrepancy between the view and the model. The view shows:
- "6 days ago"
while the model contains:
- 3/11/2010
The user can enter other dates that i cannot recognize:
Birth Date: mercury was in the 7th house
i have no idea how to turn this into a date, and i really am not going to try. i'm just going to tell to user to enter in dates like a normal person. But the question is: how do i show the user text they typed?
The view is used by the 开发者_Python百科controller to display what's in the model. In this case the model does not contain "mercury was in the 7th house" - it cannot: the model for a birth date is a DateTime
which cannot hold this string.
And when the user tries to hit save, and i check if the BirthDate is valid, i'm going to (correctly) look at the model, which contains:
3/11/2010
and assume that the user has entered in a proper date. Except that they didn't.
I think you underuse your controller.
Controller has access to the view as you said, but actually you only use it to retrieve data from the model.
It is perfectly valid to fill view from the controller with controller originated data, especially in validation process of incoming data.
In your case, the Model could still be responsible from accepting data pre-parsed from the controller.
The functional scope of your model may vary from dumb/data storage to intelligent entity with parameter validating methods.
The controller has for role to act as a semantic frontier between view & model. view data may be expressed in view oriented semantics,model has its own semantics (like date format)
In your case "6 days ago" is a value ,related to date view field (field being the real view oriented semantics of the container holding the string "6 days ago")
3 options for you:
- having a smart model & trivial controller , model being responsible to return "invalid value" return code to the controller if value is not compatible with model date ingestion method.
- having a smart controller & trivial model, letting the controller do all the parsing
- relatively smart controller & relatively smart model (the best option). Each acting in a specific semantic field. ie : the controller parses syntax errors , transforms date to comply with the model interface,while the model handles logical errors based on the date value it receives.
In all error cases, the controller is responsible to fill the view with data, whether they come from model's or controller's parsing.
Since the controller first received the incoming data, it is free to update the view with incoming data + related error info , not only model originated data.
There are basically two ways:
The submitted data is usually already available somewhere in the scope of the view. In for example a webapplication, it's usually still available as request parameter. Just check its presence and display accordingly in the view.
Get hold of both the initial value and the submitted value in an extra abstract layer. When the submitted value converts and validates without errors, update the initial value and remove the submitted value, so that the view knows which value to display. Most component based MVC frameworks like Sun JSF and MS ASP.NET MVC works that way.
精彩评论