如何使用Custom方法/ ActionLink进行分页?

时间:2012-04-26 18:25:40

标签: c# asp.net asp.net-mvc-3 razor

我可能在这里完全错了,但这部分是我要问的。

我正在使用MVC3创建一个博客,我遇到了一些问题。我的主页目前正确列出每篇博客文章及其相应的评论和主题。我希望它仅限于许多帖子,所以这是我在HomeController中的代码。

public class HomeController : Controller
{
    private MyDB db = new MyDB();

    public ActionResult Index()
    {
        var posts = (from p in db.Set<BlogPost>()
                     orderby p.DateCreated descending 
                     select new PostViewModel
                                {
                                    Title = p.Title,
                                    DateCreated = p.DateCreated,
                                    Content = p.Content,
                                    Topics = p.Topics,
                                    Comments = p.Comments,
                                    CommentCount = p.Comments.Count
                                }).Take(5).ToList();

        IEnumerable<Topic> topics = from t in db.Topics
                                    select t;

        var blog = new BlogViewModel
        {
            Post = posts,
            Topics = topics.Select(t => new SelectListItem { 
                Value = Convert.ToString(t.id),
                Text = t.Name
            })
        };

        return View(blog);
    }
}

正如我所说,这很好。我将主题分开,因为我想最终按那些排序(我也不知道从哪里开始,但这是另一个故事)。

我的主要问题是我希望在5个选定的帖子下面有一个“下一个”和“上一个”按钮,点击后,抓住下一个5或之前的5.我被告知要使用...

@Html.ActionLink("Next >>", "ActionName", "Home", Custom arguement?)

解决方案的类型,我在HomeController中编写自定义方法并抓住下一个或前一个5.这是否正确?我想了解这样的最佳使用场景。我对MVC3完全不熟悉,所以我不是在寻找快捷方式,我觉得我可能已经做了一些。

感谢您的帮助。

5 个答案:

答案 0 :(得分:0)

我看到两个最佳方案:

您可以使用Ajax / Jquery并执行此操作。

两个你使用'部分'视图。这样,当有人按下接下来的五个操作链接时,您不会影响整个视图。因此,您只对帖子进行局部视图,然后控制器接收下一个五的请求,并返回一个包含五个帖子项的模型的部分视图。

选择哪一个你觉得更舒服,但如果你正在学习MVC,那么选择二对你来说可能更适合练习。

答案 1 :(得分:0)

您可以查看:http://nerddinnerbook.s3.amazonaws.com/Part8.htm。 此外,如果您想使用ajax请求获取数据,我建议您将包含数据的部分视图转换为字符串(Return Razor partial view using JSON (ASP MVC 3))并使用jquery加载它(http://api.jquery.com/load/)。

答案 2 :(得分:0)

我在您的控制器上请求另一个操作方法(使用Ajax,或者正常),然后重复使用您用于初始页面渲染的相同视图。

public ActionResult Index(int? pageNumber)
{
     if(!pageNumber.HasValue)
         return Index();

     var posts = ...; // get posts

     var set = posts.Skip(pageNumber * itemsPerPage).Take(itemsPerPage);
     // or pageNumber - 1 if you want to be 1-index based

     return View(...); //or PartialView() if doing ajax, or even Json() if you want to bind on the client side
}

答案 3 :(得分:0)

https://github.com/TroyGoode/PagedList

public class HomeController : Controller
{
    public ActionResult Index(int? page)
    {
    var posts = (from p in db.Set<BlogPost>()
                 orderby p.DateCreated descending 
                 select new PostViewModel
                            {
                                Title = p.Title,
                                DateCreated = p.DateCreated,
                                Content = p.Content,
                                Topics = p.Topics,
                                Comments = p.Comments,
                                CommentCount = p.Comments.Count
                            });

    var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1)
    posts = posts.ToPagedList(pageNumber, 25); // will only contain 25 posts max because of the pageSize

    var blog = new BlogViewModel
    {
        Post = posts,
        Topics = topics.Select(t => new SelectListItem { 
            Value = Convert.ToString(t.id),
            Text = t.Name
        })
    };

    return View(blog);
    }
}

答案 4 :(得分:0)

您可以像下面的示例代码一样创建您的控制器:

    public ViewResult List(string category, int page = 1) {

        ProductsListViewModel viewModel = new ProductsListViewModel {
            Products = repository.Products
                .Where(p => category == null ? true : p.Category == category)
                .OrderBy(p => p.ProductID)
                .Skip((page - 1) * PageSize)
                .Take(PageSize),
            PagingInfo = new PagingInfo {
                CurrentPage = page,
                ItemsPerPage = PageSize, //4 for example
                TotalItems =  category == null ? 
                    repository.Products.Count() : 
                    repository.Products.Where(e => e.Category == category).Count()
            },
            CurrentCategory = category
        };
        return View(viewModel);
    }

在您的视图中,您放置了此自定义HTML帮助程序:

<div class="pager">
   @Html.PageLinks(Model.PagingInfo, x => Url.Action("List", 
    new {page = x, category = Model.CurrentCategory}))
</div>

以下是帮助者的代码:

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 example was taken from this book