Reputation: 12438
I am trying out a sample in ASP.NET MVC 4. He create an extension method for HtmlHelper. Below is the code:
public static class PagingHelpers
{
public static MvcHtmlString PageLinks(this HtmlHelper html,
PagingInfo pagingInfo,
Func<int, string> pageUrl)
{
StringBuilder result = new StringBuilder();
for (int i = 1; i <= pagingInfo.TotalPages; i++)
{
TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag
tag.MergeAttribute("href", pageUrl(i));
tag.InnerHtml = i.ToString();
if (i == pagingInfo.CurrentPage)
tag.AddCssClass("selected");
result.Append(tag.ToString());
}
return MvcHtmlString.Create(result.ToString());
}
}
This is used by a view as below:
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))
This is the controller that defines the action method for the view:
public ViewResult List(string category, int page = 1)
{
ProductsListViewModel model = new ProductsListViewModel {
Products = repository.Products
.Where(p => category == null || p.Category == category)
.OrderBy(p => p.ProductID)
.Skip((page - 1) * PageSize)
.Take(PageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = PageSize,
TotalItems = repository.Products.Count()
},
CurrentCategory = category
};
return View(model);
}
Based on the results of the extension method (and using breakpoints), the value of x is the 'page' parameter on the List action method in the controller. How did x get a hold of that? Or how did the value get passed to x? I've mostly used delegates on LINQ when I am working with collections; the value passed as parameter is from the collection (iterated). But I can't seem to grasp this.
Upvotes: 0
Views: 76
Reputation: 8474
The PagingHelpers.PageLinks
extension method is using the Func<int, string>
to generate URLs.
Since the actual generation of the URL is provided by the View, not the extension method, the extension method is just using the mechanism defined in the view as the URL generator.
The extension method works like this:
Func<int, string>
passed into me
int
and get back a string
)href
.So look at the view:
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))
The Func<int, string>
is saying "When I'm given an int x
, call this code with it". This way the URL generation is controlled by the view. The extension method is inly interested in the resulting HTML generated by the Url.Action
.
Upvotes: 1
Reputation: 3277
Basically Func<int, string> pageUrl
means a function with one int param and which returns string.
You are calling this function in for loop
by:
tag.MergeAttribute("href", pageUrl(i));
When you are calling pageUrl it basically calls something like:
public String SomeFunction(int x)
{
return Url.Action("List", new { page = x, category = Model.CurrentCategory });
}
So x => Url.Action("List", new { page = x, category = Model.CurrentCategory })
here means anonymous function which just wraps Url.Action
function
Upvotes: 1