2012-02-27 17 views
0

我有一个带有过滤器的搜索表单。 1过滤器是范围,这是一个数字下拉。我有一个视图使用一个查看范围(我的数据库表)ienumerable视图和控制器我填充这个和所有的作品,因为它应该...直到表单显示,用户试图再次过滤,在这种情况下,我的模型视图ienumerable现在为null。为什么它会失去价值。我是否需要每次用户重新设置一次新的过滤器......如果可以,不需要重复调​​用数据库,因为下拉列表中的值不会改变。MVC 3 Dropdownlist用于搜索的链接模态查看列表在回发中始终为空

模式的看法

public class SearchResultsViewModel 
{ 
    public int? Page { get; set; } 
    public penguin.Models.Job Job { get; set; } 
    public IPagedList<Models.Job> SearchResults { get; set; } 
    public string SearchButton { get; set; } 

    [Display(Name = "keywords")] 
    public string keywords { get; set; } 
    [Display(Name = "location")] 
    public string location { get; set; } 
    public int RangeID { get; set; } 
    public IEnumerable<Models.SearchRange> Range { get; set; } 

} 

控制器

const int RecordsPerPage = 25; 
    public ActionResult Jobs(ViewModels.SearchResultsViewModel model) 
    { 

     // do something with the search value      
     if (!string.IsNullOrEmpty(model.SearchButton) || model.Page.HasValue) 
     { 

      var entities = new Models.DBDataContext(); 
      var results = entities.Jobs; 

      var pageIndex = model.Page ?? 1; 
      model.SearchResults = results.ToPagedList(pageIndex, 25); 

      //Range = ViewData["Range"] as IEnumerable<Models.SearchRange>; 
     } 
     else { 
      var Data = Helpers.ModelHelpers.GetDataContext(); 
      var ranges = (from r in Data.SearchRanges select r); 
      model.Range = ranges; 
      //Range = ranges; 

     } 
     //ViewData["Range"] = Range; 
     //model.Range = Range; 
     return View(model); 


    } 

查看

@using PagedList.Mvc; 
@model ViewModels.SearchResultsViewModel   
@{ 
    ViewBag.Title = "Jobs"; 
} 
@section search { 
@using (Html.BeginForm("Jobs", "Search", FormMethod.Post, new { id = "searchForm" })) 
{ 
    <fieldset> 
     @Html.LabelFor(m => m.keywords) 
     @Html.TextBoxFor(m => m.keywords) 
     @Html.LabelFor(m => m.location) 
     @Html.TextBoxFor(m => m.location) 

     @Html.DropDownListFor(m => m.RangeID, new SelectList(Model.Range, "ID", "Range", 5)) 
     <input name="SearchButton" type="submit" value="Search" /> 
    </fieldset> 

    } 
} 
<h2> 
Jobs</h2> 
<div id="resultContainer"> 
my paged results set will go in here with a link to view job details. I then want 
it to come back here and not lose anything 
@* html.Action("Results", "Search")*@ 
@if (Model.SearchResults != null && Model.SearchResults.Count > 0) 
{ 
    foreach (var result in Model.SearchResults) 
    { 
    <hr /> 
    <table width="100%"> 
     <tr> 
      <td valign="top"> 
       <div style="font-weight: bold; font-size: large;"> 
        @Html.Raw(@result.Title.Truncate(50))</div> 
       @Html.Raw(@result.summary.Truncate(50))<br /> 
       </td> 
        </tr> 
    </table> 

    } 

    <hr />   

    @Html.PagedListPager(Model.SearchResults, page => Url.Action("Jobs", new RouteValueDictionary() { 
       { "Page", page }, 
       { "Job", Model.Job } 
       }), PagedListRenderOptions.DefaultPlusFirstAndLast)} 
    </div> 

回答

0

如果下拉列表中的值不会改变(曾经),那么你可能应该缓存它们服务器端,每次只重用这些值。您将需要每次向模型提供值,因为数据不会在连续请求之间持续存在。 MVC中没有视图状态来保留这些值。实际上,这是一件好事。

private static IEnumerable SearchRange { get; set; } 

static SearchController() 
{ 
    SearchRange = new MyDataContext().SearchRanges.AsEnumerable(); 
} 

public ActionResult Jobs(ViewModels.SearchResultsViewModel model) 
{ 
    model.Range = SearchRange; 
    ... 
} 
+0

请小心使用静态集合,因为它们不是线程安全的,您可能会遇到线程阻塞问题,如果您有多个人使用它,将导致您的应用程序挂起。您可以使用线程安全集合(System.Collection.Concurrent),或者您可以使用内置的HTTP缓存机制。我更喜欢使用'HttpRuntime.Cache',因为它也适用于单元测试的环境中,因为'this.HttpContext.Cache'需要HTTP上下文(或者需要模拟一个)。 – Makotosan 2012-02-27 21:28:47

+0

我会更关心它是不是只读集合。就个人而言,如果数据永远不会改变,我可能会在代码中实现它,例如'enum',或通过配置而不是从数据库中获取。使用缓存将是一个选项,如果它很大,但你可能必须建立一个刷新机制。如果使用EF,'DbSet '类对于静态实例是线程安全的。 – tvanfosson 2012-02-27 21:36:52

+0

谢谢你的帮助。 @tvanfosson在你的例子中如何缓存项目服务器端,它似乎对我来说每次都获得搜索范围,但我可能会失去一些东西。我可以使用一个枚举建议也,但我想学习如何做的事情,所以在某些时候,我将需要一个下拉的项目,可能会改变日常等谢谢 – Jonnymaboy 2012-02-27 22:45:27