2014-10-09 36 views
0

我正在嘗試使用Asp.Net MVC4和Razor爲報告執行過濾頁面。要做到這一點,我開發了包含三個次要視圖模型對象列表(我將其呈現在小格子內頁)一個ViewModel類類EditorTemplates問題 - 在Post事件中僅返回列表中的第一個元素

public class DeviationReportViewModel 
{ 
    [Display(Name = "Type")] 
    public int Type { get; set; } 
    [Display(Name = "Companies")] 
    public List<Company> Companies { get; set; } 
    [Display(Name = "Departments")] 
    public List<Department> Departments { get; set; } 
    [Display(Name = "Employees")] 
    public List<Employee> Employees { get; set; } 

    public List<Event> Events { get; set; } 
    [Display(Name = "Event")] 
    public Event ChosenEvent { get; set; } 
    public string Event { get; set; } 
    public string FileType { get; set; } 
} 

公司,部門和員工類基本上包含ID(INT) ,名稱和描述(兩個字符串),外鍵描述的字符串屬性(例如員工所屬的部門)和Selected(布爾)屬性。對於每一個我開發像這樣的一個EditorTemplate:

// ~\Views\Shared\EditorTemplates\Employee.cshtml 
@model Model.ViewModels.Employee 

<tr id="@Model.Id"> 
    <td> 
     @Html.CheckBoxFor(m => m.Selected, new { @class = "selectEmp" }) 
     // I use this for filtering values between tables, using javascript 
     // (i.e.: to show only Employees from a Department) 
    </td> 
    <td> 
     @Html.HiddenFor(m => m.Name) 
     @Html.DisplayFor(m => m.Name) 
    </td> 
    <td> 
     @Html.HiddenFor(m => m.Department) 
     @Html.DisplayFor(m => m.Department, new { @class = "fk" }) 
    </td> 
</tr> 

當我從數據庫取回這些名單,它們包含幾個對象(即:員工名單有10個對象),但是當我回來後與選擇的視圖模型,員工列表只包含一個對象。公司和部門名單不會發生這種情況。由於我不會從列表中刪除任何東西(我只是使用「Selected」屬性來正確地過濾它們),哪裏出錯?

(我已經通過thisthisthis文章一派,但我還是不明白)

編輯 - 用於過濾(jQuery的數據表)JS腳本

function GetColumn(class) { 
    if (class == '.selectCom') { 
     return 1; 
    } 
    else { 
     return 2; 
    } 
}; 

//this function returns a keyword list for filtering 
function GetSearchArray(tbl, searchClass) { 
    if (searchClass === null || searchClass === undefined) { 
     searchClass = ''; 
     return new Array(); 
    } 
    else { 
     var searchArray = new Array(); 
     $(searchClass).toArray().forEach(function (item, index, array) { 
      if ($(item).is(':checked')) { 
       tbl.settings.currentColumn = GetColumn(searchClass); 
       searchArray.push($(item).parents('tr')[0].cells[1].innerHTML); 
      } 
     }); 
     return searchArray; 
    } 
}; 

// this function effectively filters a child table based on what is selected on parent table 
function TableFilter(parentTableId, parentClassName, childTableId, childClassName) { 
    var tbl = $(childTableId).dataTable(); 
    var keywords = GetSearchArray($(parentTableId).DataTable(), parentClassName); 
    var filter = ''; 
    keywords.forEach(function (item, index, array) { 
     filter = (filter !== '') ? filter + '|' + item : item; 
    }); 
    tbl.fnFilter(filter, GetColumn(childClassName), true, false, false, true); 
}; 

// These events call the filtering function and clear what is selected on child tables. 
$('.selectCom').change(function() { 
    TableFilter('#tbCom', '.selectCom', '#tbDep', '.selectDep'); 
    $('.selectDep').prop('checked', false); 
    $('.selectEmp').prop('checked', false); 
}); 

$('.selectDep').change(function() { 
    TableFilter('#tbDep', '.selectDep', '#tbEmp', '.selectEmp'); 
    $('.selectEmp').prop('checked', false); 
}); 

先謝謝你。

+0

你在這裏的代碼看起來很好,所以必須有其他一些問題。劇本在做什麼?你是否禁用任何元素? – 2014-10-09 21:46:14

+0

@StephenMuecke我已經添加了腳本細節。感謝您的興趣。 – 2014-10-10 14:04:41

+1

很難說,因爲我不熟悉'jQuery DataTables',但回發一個集合的關鍵是索引器必須開始一個零並且是連續的。如果你篩選出的項目(例如,你有''如果缺失)。如果這是問題,那麼你將需要一個'for'循環並添加一個帶有索引屬性的隱藏輸入,它允許你發回不連續的索引項('') – 2014-10-11 01:03:00

回答

0

這裏,問題出現在客戶端,因爲DataTables.Net 的「fnFilter」函數從我的viewmodel中的列表中有效地移除了對象。這樣,我認爲「fnFilter」與EditorTemplate的索引相混淆(並且加擾它們),並且在POST上,ASP.NET MVC不知道如何重構這些索引。

那麼我們該怎麼辦?我改變了我的客戶端過濾功能,以隱藏過濾行(爲每個過濾行添加「display:none」類)。所以,當我們發回表單時,列表保持不變,包括選定的值。指標是完美的。

感謝@StephenMuecke給了我線索。

0

你將不得不做這樣的事情Example of Posting Collections to Controller

您的編輯器模板必須是foreach()循環,並遍歷循環並手動設置每個元素的名稱和ID。所以,像下面的東西。

for(int i = 0; i < Employees.Count ; i++){ 
    <input type="textbox" name="Employees[i].Name" id="Employees[i].Name" /> 
    ... 
    ... 
    // if Employees is a list and contains a list as a property then 
    for(int x =0; x < Employees[i].Departments.Count; x++){ 
     <input type="textbox" name="Employees[i].Departments[x]" ... 

我知道部門不是一個清單,但這是你如何做的一個例子。

+0

感謝您的回答,但正如我在[這裏](http://stackoverflow.com/a/11458302/1475630)中提到的第三個鏈接所述,我們不需要迭代集合,因爲編輯器模板有效地爲我們做... – 2014-10-09 18:42:19

相關問題