2017-07-10 86 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