2017-07-10 41 views
-1

我正在运行asp.net 4 mvc,并且我创建了默认为列表中第一个条目的日期的DropDownList。当我选择一个条目时,我调用一个控制器函数并做一些处理。但是,当我的页面进行回发时,不是显示我选择的列表项目,而是再次显示原始默认列表项目。DropDownList未设置选定的值

如何让我的页面显示我从列表中选择的最后一个项目?我花了整整两天的时间搜索这个网站和互联网寻找解决方案,但我没有尝试似乎工作。任何援助将不胜感激。

我的HTML视图

@Html.DropDownList("selectList", Model.ReverseMonthsLists(), 
    new { @onchange = "CallChangefunc(this.value)" }) 
<script> 
    function CallChangefunc(val) { 
     window.location.href = "/dashboard/Report_Performance?id=" + val; 
    } 
</script> 

我的视图模型

public SelectList MonthList { get; set; } 

public IEnumerable<SelectListItem> ReverseMonthsLists() 
{ 
    var selectListItems = GetDates() 
     .Select(_ => _.ToString("MMM yyyy")) 
     .Select((dateString, index) => new SelectListItem { Selected = index == 0, Text = dateString, Value = dateString }) 
     .ToList(); 
    return selectListItems; 
} 


public static IEnumerable<DateTime> GetDates() 
{ 
    DateTime startDate = new DateTime(2017, 6, 1).Date; 
    var currentDate = DateTime.Now.Date; 
    int numberOfMonthsToShow = (currentDate.Year - startDate.Year) * 12 + currentDate.Month - startDate.Month; 
    var dates = new List<DateTime>(numberOfMonthsToShow); 
    currentDate = currentDate.AddMonths(-1); 

    for (int i = 0; i < numberOfMonthsToShow; i++) 
    { 
     dates.Add(currentDate); 
     currentDate = currentDate.AddMonths(-1); 
    } 

    return dates; 
} 

我的控制器

[RequireLogin] 
public ActionResult Report_Performance(string id) 
{ 
    DateTime newDate = DateTime.Now.Date.AddMonths(-1); 
    if (id != null) 
     newDate = DateTime.Parse(id); 
    var aVar = Models.Reporting.ListingStatsReportingViewModel.GetStats(userCurrentService.CompanyId.Value, Models.Reporting.DateTimePeriod.Monthly, newDate); 
    return this.View(aVar); 
} 
+0

能告诉你的'GetStats'方法的代码?我猜测它总是返回相同的数据,所以它会帮助我们看到底下发生了什么。 – sleeyuen

回答

1

的问题是在这里:

window.location.href = "/dashboard/Report_Performance?id=" + val; 

这至关重要告诉浏览器导航到一个新的页面,这是一个HTTPGET操作。因此,您的当前设置与新页面的设置之间没有关联。

就好像你刚刚进入地址栏并按回车。它会发布一个全新的默认页面。

有很多方法可以解决这个问题。最简单的方法是使用一些JavaScript查看URL并提取id查询参数,然后在下拉框中选择与id对应的项目。

另一种方法是根据控制器中的ID设置下拉列表的选定值。

在控制器:

ViewBag.SelectedItem = id; 

在View:

@Html.DropDownList("SelectedItem", Model.ReverseMonthsLists(), ...) 
+0

我明白你在说什么。我在.Net和JavaScript中很新,所以我不太明白如何去做。您可以请发表一个我将如何实施您的解决方案的代码示例? – csharpMind

+0

@csharpMind - 你发布的代码并不匹配,所以我只是按你发布的内容去做。例如,您将GetStats()方法的结果作为模型传递给View,并且您没有显示它是什么。看起来,基于你调用模型的方法,就好像你返回对ViewModel的引用。 –

+0

感谢您的回复。 GetStats()方法正在按照预期返回所请求的统计信息。我传递给它一个字符串值。 DropDownList automaticall默认为列表中的第一个条目。在这种情况下,“2017年7月”。但是,如果我使用下拉菜单选择“2017年6月”,则会调用Report_Performance控制器函数,并执行GetStats()方法。结果返回到视图,但我的下拉菜单显示“2017年7月”,而不是“2017年6月”。我希望组合框显示“2017年6月”,这是我选择的。 – csharpMind

2

你可以改变你代码如下:

假设是由GetStats方法在Report_Performance操作返回模型类是MyStats其中包含一个名为SelectedDateString一个字符串属性(你需要这个属性添加到您的视图模型类)。

更新视图的标记:

@model MyStats 
@Html.DropDownList("SelectedDateString", Model.ReverseMonthsLists(), 
    new { @onchange = "CallChangefunc(this.value)" }) 
<script> 
    function CallChangefunc(val) { 
     window.location.href = "/dashboard/Report_Performance?id=" + val; 
    } 
</script> 

更新控制器:

[RequireLogin] 
public ActionResult Report_Performance(string id) 
{ 
    DateTime newDate = DateTime.Now.Date.AddMonths(-1); 
    if (id != null) 
     newDate = DateTime.Parse(id); 
    var aVar = Models.Reporting.ListingStatsReportingViewModel.GetStats(userCurrentService.CompanyId.Value, Models.Reporting.DateTimePeriod.Monthly, newDate); 

    //This will make sure that the model returns the correct value of the property as a string. 
    aVar.SelectedDateString = id; 

    return this.View(aVar); 
} 

Html.DropDownList()作品通过从在其中是相同的名称作为将DropDownList本身的名称的模型string property获取数据。

对于你的情况,你需要使用javascript或jquery设置DropDownList值,因为它没有连接到模型属性。

让我给你举个例子:可以通过使用

@Html.DropDownListFor(m => m.PreferredContactMethod, Model.PreferredContactMethods, "") 

@Html.DropDownList("PreferredContactMethod", Model.PreferredContactMethods, "") 

在这两种情况下,PreferredContactMethod创建于MVC 一个下拉列表是一个字符串属性我连接到视图的模型 - 通过在视图顶部指定@model PreferredContactModel完成。

就你而言,你的列表名称是selectList,如果指定模型连接到视图,并且如果模型中有一个属性获取选定日期,则需要将下拉列表的名称更改为它。

我希望它是有道理的,如果有任何问题,请回复评论。我想帮助这一点。

+0

此过程中涉及的所有代码都张贴在上面。当你说“如果指定的模型连接到视图,并且模型中有一个属性获取选定的日期”我不知道你的意思。我的模型连接是“public SelectList MonthList {get; set;}”,如上所示。我错过了什么? – csharpMind

+0

你在视图中放置了@ @ model'语句吗?而且,'return this.View(aVar)'的返回语句是否会使您回到相同的视图? – Yatin

+0

感谢您的回复。 return语句使我回到相同的视图,列表中的第一个项目显示为我第一次来到视图,而不是显示我选择的列表项以访问控制器。上面显示了视图上代码的总和。 – csharpMind