2014-10-09 52 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

相关问题