Consider u have a big front page include ton of data from database (like new products,best products, latest posts, banners,sliders,etc) not only static views like header or something like that. related to this post
it seems this is better to build a complex model and split page to small partial views. but what is wrong with this way that USE ACTIONS and split page like this:
#{
ViewBag.Title = "Home";
}
#{Html.RenderAction("Header", "Home");}
#{Html.RenderAction("Sliders", "Home");}
#{Html.RenderAction("Specials", "Home");}
#{Html.RenderAction("Services", "Home");}
...
#{Html.RenderAction("Footer", "Home");}
so you no need to use a complex model.
EDIT: my main question is what is wrong with using actions in view instead partial views. in this way you no need to send a complex model to view and use its parts for partial views
Using partial views makes the code easier to maintain, since partial views are by convention named with an underscore like "_PartialView"
this way you can easily see in your solution which views are partial and which are not.
How you want to implement them is a question of heart and experience most often, but always strive for best practice.
That is, try to code the way you think you want to read code when coming back after a long break from it, or how you want to find code written by others that you think is easy to understand fast.
The less cognitive strain, the better, whether the code is for you or someone else.
Related
I am beginning with MVC ASP.NET and stumbled upon a problem. There is a paragraph (some 5 sentences) I would like to use on several of my child pages. This text changes quite often so I would like to have it defined on 1 place so I dont have to update like 10 pages when it changes again.
Problem is, that I dont know how to do it. I was thinking about using CSS (which should be used for styling, not text) or sections (doesnt work, as each child page needs its own sections defined).
Could someone advise me the most optimal and "correct" way to achieve this? I would like to define this paragraph at one place and then "call it" from the child page without need to use the database. Which approach should I choose?
Thank you
Create one partial view and call in your main view:
#Html.Partial("YourPartialViewName", Model) //if you have some dynamic data pass in model
I have a Course Model which goes the controller and views in a restful way.
For my Course show, it is fully featured. I now want another Course show which will have a simplify page and it like to the original course show.
How can I implement this? I want it to be restful, so in my controller there should only be show, update, index, etc.
Should I create another controller that have an different name from the Model? E.g. Course2?
If it is an admin view vs. public view, I would have entirely different namespaces for two different RESTful controllers. Or if you think you're going have this summary vs. full view thing a lot, create namespaces based on that distinction.
Another option is to encoded the differences in a single ERB template. Or you could actually have the show action render different templates from the same action using some conditional logic.
Without more context though, I can't really say what's the best option. I am personally against creating non-RESTful actions unless it's really going to be a one-off thing. Non-RESTful actions tend to get out of hand in my experience and controllers can get really ugly and unintuitive.
If this is truly just displaying a subset or a different arrangement of the same information, then I think this is a job for the view. At most the controller can use the same action, but select a different view to render, such as might be done if the user wanted to see html vs plain text.
The controllers job is to interpret the model and the views job is to collect and display information. I think you would be concerned about the view having logic in it if you what you describe as a "summary" were more than just a subset of the info, for example if you started to calculate the distances being traveled or how long it would take or how much it would cost based on the data that is provided, then that would be bad.
So I this is just a subset, then I would suggest either rendering partials based on some variable set by your controller, or if organization of the display needs to be substantially difference, then the controller can select a different template to render.
I have a model with attibutes name, title, description ect. If the name is by example weather-foracast I want to show an extra html element
= high_chart("my_id", #chart)
in the show template, wich generates a nice chart. When the page is not weather-foracast i don't want to show the chart.
What is the best approach? Conditions in the view?
Your problem looks really close to the Exhibit Pattern presented in Object on Rails.
Simply explained, the solution proposed is to wrap your model in a decorator (or multiple decorators) chosen using the state of your model (in your case the name of the record).
I cannot explain it as well as it is explained in the book but that Pattern is so useful that Avdi Grimm made a gem out of it : https://github.com/objects-on-rails/display-case
I know this answer is totally over the top, but something to consider is moving your conditional logic outside of your views.
Maybe going with the View Presenter pattern, see this:
About presenter pattern in rails. is a better way to do it?
Presenters are ruby objects and can be tested really easily.
Whereas having tons of logic inside the view is really hard to test.
Furthermore, you want isolation of logic, checking for model.name inside your view page is not the best way of MVC.
Since it looks like you're HAML, you can just use an if modifier like so:
= high_chart("my_id", #chart) if [model.name] == "weather-forecast"
where [model.name] is replaced with the appropriate code.
First of all, I have been a php programmer for a long time and I am a mvc programmer newly. I did a few minor web sites that each have one or two controller at most. But I've started a website that will be very major web site. There will be a lot of data to pass to views.
Now, normally I try to use model approach every time instead of ViewBag or ViewData approach. If the view demands more data, then I change the model class and then recompile the project. Especially, if the topic is an index page, the data to pass to the index's view changes every time. In a big web site, I'll use a lot of partial view that uses different models. So every time, I will have to change the index's model to support those partial views in the index view. if I add a new partial view into index view, I have to add the partial's model into the index's model.
I implement an IndexModel class for an index view every time when I start a website. Then I add properties to this model every time when I add a new partial view to the index.
Now is this a correct approach or should I use ViewBag or ViewData for partials' models. I think the real question is when we should use the model approach and when we shouldn't...
If you share your experiences, I would be grateful.
The MVC approach you should use always, especially for simple sites, it's save your time and make application more understandable.
If you write something larger than two pages, you need to use MVVM pattern (growth of MVC), in that case you will escape from using "partial models" with ViewModels.
Model must contain only busines logic.
Be better if you will always use ViewModel (not a Model) for returning data from a view and pass it to view, because it provides some safety.
For facilitate the procedure of copy data from Models to ViewModels use the things like AutoMaper and EmitMapper.
ViewBag and ViewData you should use only for additional data's like item colections for DropDown, or some view-text like page title.
One more advantage of MVVM pattern is better testability. If you write and support really hugh site you may write tests for some responsible parts of code.
For more details you can look at google - MVVM, ASP-MVC.
If i something not understad in you question or miss, write it in the comment ("add comment" ref).
I personally prefer to keep my sites consistant and always use Model + Viewmodel (no matter how big the site is) despite the extra work (which isn't much anyway).
It helps with maintainability. I know where and how everything is stored and coded into the site.
This might be similar to ASP.NET MVC - Populate Commonly Used Dropdownlists.
I want to populate DropDownLists. Some of it is static data. Some of it comes from the Database. A couple of times I found myself forgetting to call the code that populates my lists and sets the ViewBag accordingly. It is almost worth adding a unit test for this. The only way I think that this suits a unit test is if you place it in model/service. Is there a best practice for this kind of thing?
I'd suggest that the data is contained within the model but is perhaps constructed by a html.helper method. this way, you keep the plumbing markup out of the view and leave the controller free to invoke the neccesary view and model.
You could also of course hand it off to a partialview with an <IList<SelectList>> model.
cats and their skin :)
If you follow the spirit of the pattern then the Model should supply the View with everything it needs to present to the user that's not static. If you have static dropdown lists then you could say that these could be constructed within the mark-up. If you are passing a SelectList to the View from your Action then I'd stick it in the Model to make things simpler and more coherent.
My rule of thumb is that the data must somehow be in the model, either as a ready to use SelectList or at worst in some container that can easily be turned into a SelectList using a LINQ-to-object call.
The bottom line is that the view should never contain any non trivial code.
EDIT (answer to your comment):
I try not to put too much code in models. Models are more like a simple bunch of data gathered by the controller and used by the view.
Regarding simple and/or common things such as the days of week, I believe an HTML helper is the most elegant solution. See WayneC's answer in this question.