Need advice about IEnumerable<item> -> 3xIEnumerable<item>
What's better?
1) If i make 3 ViewBag on server and then Render my View using this ViewBags?
Server
ViewBag.LeftColumnTales = tales.Where((x, i) => i % 3 == 0);
ViewBag.CenterColumnTales = tales.Where((x, i) => i % 3 == 1);
ViewBag.RightColumnTales = tales.Where((x, i) => i % 3 == 2);
View
<div id="left_column">
@foreach (var t in ViewBag.LeftColumnTales)
{
<div class="item">
<a href="/narodnie-skazki/@t.PeopleTalesCategory.RouteNameAn/@t.RouteNameAn">@t.NameAn</a> <span>(@(new HtmlString(Html.TimeForReadingHtmlResult((int)t.TimeForReading))))</span>
@(new HtmlString(Html.PeopleTaleVoterHtmlResult((int)t.Analit)))
</div>
}
<!--end of div.item-->
</div>
or
2) If i set ViewBag.tales on server and then on View will make Converting from dynamic data to IEnumerable and devide it to 3 columns?
Server
ViewBag.Tales = tales;
View
<div id="left_column">
@foreach (var t in ((IEnum开发者_如何转开发erable<MVCFairyTales3.Models.AuthorTale>)ViewBag.Tales).Where((x, i) => i % 3 == 0))
{
<div class="item">
<a href="/avtorskie-skazki/@t.AuthorTalesCategory.RouteNameAn/@t.RouteNameAn">@t.NameAn</a> <span>(@(new HtmlString(Html.TimeForReadingHtmlResult((int)t.TimeForReading))))</span>
@(new HtmlString(Html.AuthorTaleVoterHtmlResult((int)t.Analit)))
</div>
}
<!--end of div.item-->
</div>
What's better?
To be honest I don't like any of those two. They both use ViewBag and weak typing. I am sorry but personally I get sick when I see ViewBag/ViewData.
Personally I like using view models and strongly typed views:
public class MyViewModel
{
public IEnumerable<Tale> LeftColumnTales { get; set; }
public IEnumerable<Tale> CenterColumnTales { get; set; }
public IEnumerable<Tale> RightColumnTales { get; set; }
}
which you could populate in your action:
public ActionResult Foo()
{
var model = new MyViewModel
{
LeftColumnTales = tales.Where((x, i) => i % 3 == 0),
CenterColumnTales = tales.Where((x, i) => i % 3 == 1),
RightColumnTales = tales.Where((x, i) => i % 3 == 2),
};
return View(model);
}
and in the strongly typed view:
@model MyViewModel
<div id="left_column">
@Html.DisplayFor(x => x.LeftColumnTales)
</div>
and in the corresponding display template which will be rendered for each element of the collection (~/Views/Shared/DisplayTemplates/Tale.cshtml
):
@model Tale
<div class="item">
@Html.ActionLink(
Model.NameAn,
Model.RouteNameAn,
Model.AuthorTalesCategory.RouteNameAn
)
<span>
@Html.Raw(Html.TimeForReadingHtmlResult((int)Model.TimeForReading))
</span>
@Html.Raw(Html.AuthorTaleVoterHtmlResult((int)Model.Analit))
</div>
And even better if you have to repeat this all over your pages is to put it in the _Layout using child actions as explained by Phil Haack in his blog post.
I'm not sure how you app is structured/layered, but in general I like to separate out my business/domain logic from my UI code. It sounds like whether it should be in the left/center/right column is strictly UI logic. In that case I would have my business layer retrieve/create the list of all tales, then leave it up to the UI layer to split it up however it is to be displayed.
When I'm trying to figure out if some logic belongs in the UI layer or not, I imagine that I am going to create many many UI's (web, windows, mobile phone, sharepoint webpart, etc) and ask myself if it's likely that logic (e.g. split it into 3 columns) will change between UI's. If the answer is yes, then that logic belongs in the UI layer.
精彩评论