I have an MVC3 project I'm working on that has a View with an associated strongly typed view model. I've been tasked with adding an optional section to this view that would contain the data for a second model, about half of which is shared with the first model.
My question is, what is the best way to implement this? Should I just add the object that the optional model represents to the view model and try to map values from there?
If I do it this way, how can I associate the editors with both models?
Adding the optional model to the view model is the best choice, because, unlike ViewBag, it's type safe and you can still leverage the html helpers. Just remember to check the second model for null reference before you render it (since it's optional).
For sharing properties, your view model can have special getters/setters that would mantain both models synchronized internally.
I think I understand what your asking and this is how I have accomplished it in the past.
Add the optional model as a parameter in the view model and then create a partial view that is typed to that optional model. If the criteria is met that allows that partial view to display then you pass the viewmodel.optionalmodel to that partial view.
You just have to be a bit careful about the overlap of parameters causing any headaches (as in null references)
Related
I have a form that will load some fields when the page is requested and some other fields that will be loaded as the user choses one option in a dropdown. The fields that should be loaded upon selection are EditorTemplates. Is there a way I could make it work without the need to refresh the page (i.e a partial view requested via ajax) and keeping the "binding" to my viewmodel?
Yes, this is possible as long as you respect the naming conventions of your input fields so that the default model binder can understand them. Here's an example of those conventions for lists. And here's a great article illustrating how you could implement editing a variable length list.
I am aware of this question, but the original poster accepted a solution that didn't involve nesting. I definitely want to nest partial views (unless, of course, there's a better way.)
I have a page that can Ajax-load one of several partial views, depending on the user's actions in the main view. (The views are partial because my understanding is that if you want to load significant additional content from an Ajax call, you need to return a PartialViewResult from your call.) The several partial views have one common element, a dropdown, which I'd like to factor out into its own partial view.
But this isn't working. My partial views each have an associated view model, which is their model. For the nested partial view, I'd like to pass the value of a single field, a nullable int, from the parent view's view model, as the model for the nested partial view.
But at run time I get an error saying that my partial view needs a Nullable<int> but received X, where X is the type of the view model associated with the parent partial view.
So my question is twofold:
Is nesting partial views simply not allowed? (In which case, I wish the framework would check for the situation and throw an error that says so explicitly.)
Is there a way to get the effect I want, of a factored-out common interface element, other than with a partial view? I have considered, but not tried, creating an edit template, because I believed that what wouldn't work for partial views wouldn't work for those, but I could be wrong.
ETA: I found my problem: when you pass a null value for the model into HtmlHelper.Partial or RenderPartial, the rendering engine subsitutes the model of the calling partial view in place of that null, assuming that you simply didn't pass a model.
Which is not true in my case: my Nullable<int> is Nullable because, until it's set, it's null! The null is semantically meaningful!
But this is why I was having the problem.
Yes, you can nest partial views. Just make sure you pass in the correct model. HtmlHelpers are useful here, as you can encapsulate the call to RenderPartial with the full view path and ensure the correct model is used.
example
public static void RenderSomePartial(this HtmlHelper helper, int? i)
{
helper.RenderPartial("~/Views/Shared/SomePartial.cshtml", i);
}
Yes, you can. It can get a bit messy if you need to pass models around though. If you're using strongly typed models, try using DisplayTemplates or EditorTemplates instead of partials.
you can use render partial in your parent view and call some child view
also you can pass data with view bag
when you call a partial view from parent the data you pass from controller to parent view can pass to child view
i use the view bag to send my data to child view
This is all hypothetical, and wondering how and if this is possible.
I have two different strongly-typed views that use two different models. For example, I have a View1.cshtml, and View2.cshtml. Each has it's own model: View1Model.cs and View2Model.cs. Each of the view pages uses a common layout (_Layout.cshtml) that has a PartialView (_WhoAmI.cshtml).
In the View1Model.cs there is a UserID field (with various other fields) and the View2Model.cs also contains the same UserID (with different fields than View1Model.cs).
The partial view will lookup the UserID and display the User's information in a small display .DIV.
What is the best way to do this and keep the PartialView strongly-typed? Is it even possible when both models of the view are so different (other than the UserID)? If so, if I use this PartialView again in the _Layout, how do I keep it from doing the User lookup two times in the Layout page for each time the partial is called?
Thanks in advance!
Instead of Html.Partial you could use Html.Action and have a child action rendering the partial and doing the necessary lookups.
I assume that if partial view has model of type dynamic then what you ask might be possible, but haven't tried it myself. At least MSDN says that dynamic variables are bypassing static type checking and at runtime they are only checked for existence of specific methods that were called from code.
in the tutorials from http://www.vainolo.com/tutorials/ the position of the model is saved in the model. I want to save all data to file and want to get the same view, when I load the file.
Searching for an answer for this question, I got another more important question:
Is the GEF really a MVC framework?
GEF Controllers tells the mvc controller role is taken from the EditPart. It creates the specified objects.
Regarding the examples the controller holds view parts, but the mvc pattern tells, that the controller only reacts on user interaction and tells the view, it has to update or what ever.
Concluding on it the following code is wrong, because it is part of EditPart and it changes:
public void refreshVisuals(){
IPersonFigure figure = (IPersonFigure)getFigure();
Person model = (Person)getModel();
figure.setName(model.getName());
figure.setSurname(model.getSurname());
}
Regarding wikipedia the view has an observer on the model, so the following sentence from GEF is wrong, isn't it?
The EditPart syncs the actual model state to the view and implements the observer.
In the MVC pattern, the controllers must listen to the changes of the model. In GEF, EditParts are the controllers so they must listen to their model to update the view according to the new state of the model.
So what is correct?
To prevent cross-posting have a look on http://www.eclipse.org/forums/index.php/m/755178/.
The wikipedia states a the start of the article on MVC that " MVC comes in different flavors (MVC overview). Sometimes the view can read the model directly and update itself, sometimes this is done by the controller.
The primary concept that MVC provides is decoupling the presentation from the view, which should contain no logic. Changes to the model are executed by the controllers, and changes to the view are caused when the model is changed. But this does not mean that the controller can't be the one who updates the view when the model changes. Someone has to do it, right? I personally think that having the view directly read from the model is not a good practice since it makes them too dependent, and that model and view should be completely separated. This is great when you have to make changes in your model (for example a field is changed from being real to being calculated) - you don't have to change your view (but you may have to change your controller, but this is normally easier).
Hope this clears things up for you.
I have a conditional business logic that determines whether a property from a model should be displayed in a view. according to best practices where would be the place to implement it?
Implementing this logic in the view level does not seem right to me.
Thanks
IMO, it is belonged to the Model. I would put that business logic in IsRequiredYourProperyName property in the model.
Really? I would have thought that would be fine in the view provided you're passing the boolean indicating whether or not it should be displayed as part of the ViewModel. The view shouldn't be querying an outside resource to see if it should render certain UI elements, but if everything it needs to determine what to render is in the ViewModel, what's wrong with a simple if{} statement? Alternatively if a conditional display property is common you could create a custom DisplayTemplate or EditorTemplate and for it and implement the logic there.
So your ViewModel should wrap everything you want to send to the view. in your case it sounds like it should wrap your DomainModel and some sort of dictionary or KeyValuePair collection detailing if each property should be displayed or not as booleans. That's what I would do anyway.