【问题标题】:Returning a Tuple List from an action and rendering it in the View model ASP.NET从操作返回元组列表并在视图模型 ASP.NET 中呈现它
【发布时间】:2018-09-08 09:07:32
【问题描述】:

我一直在为这个而疯狂,我创建了一个返回元组列表的函数,接下来是将该列表存储在另一个我想在视图中呈现的列表中。

元组List是不同类型的Lists。

控制器:

 public List<Tuple<List<string>, List<TimeSpan>, List<TimeSpan>, List<int>, List<int>, List<TimeSpan>, List<TimeSpan>>> completeStats(int EnrollNumber, DateTime StartDate, DateTime EndDate)
        {

//some code

  List<Tuple<List<string>, List<TimeSpan>, List<TimeSpan>, List<int>, List<int>, List<TimeSpan>, List<TimeSpan>>> generalList = new List<Tuple<List<string>, List<TimeSpan>, List<TimeSpan>, List<int>, List<int>, List<TimeSpan>, List<TimeSpan>>>();

//some more code

   List<string> Name = new List<string>();
            List<TimeSpan> ArrivalTime = new List<TimeSpan>();
            List<int> FineList = new List<int>();
            List<TimeSpan> ArrList = new List<TimeSpan>();
            List<int> MinList = new List<int>();
            List<TimeSpan> DepartList = new List<TimeSpan>();
            List<TimeSpan> TimeSpentList = new List<TimeSpan>();


            for (int i = 0; i < fineList.Count(); i++)
            {
                if (fineList[i] > 0)
                {
                    Name.Add(empObj2.FirstName);
                    ArrivalTime.Add(AT);
                    FineList.Add(fineList[i]);
                    ArrList.Add(ArrivalList[i]);
                    MinList.Add(minutesList[i]);
                    DepartList.Add(departList[i]);
                    TimeSpentList.Add(timeSpentList[i]);
                }
            }

 generalList.Add(new Tuple<List<string>, List<TimeSpan>, List<TimeSpan>, List<int>, List<int>, List<TimeSpan>, List<TimeSpan>>(
               Name, ArrList , ArrivalTime, MinList, FineList, DepartList, TimeSpentList

                ));
            return generalList;
}

现在在索引操作中:

 public ActionResult Index(int? EnrollNumber, DateTime? StartDate, DateTime? EndDate)
        {

//some code

  var generalList2 = new List<Tuple<List<string>, List<TimeSpan>, List<TimeSpan>, List<int>, List<int>, List<TimeSpan>, List<TimeSpan>>>();


//the line below does not work, why?
  //generalList2.Add(completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate));

//the line below works but this does not add all the list but only the last one
  //generalList2 = completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate);

//this works but obviously is not a good approach and slows down ALOT

 generalList2.Add(new Tuple<List<string>, List<TimeSpan>, List<TimeSpan>, List<int>, List<int>, List<TimeSpan>, List<TimeSpan>>( 
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item1,
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item2,
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item3,
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item4,
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item5,
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item6,
                            completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate).FirstOrDefault().Item7
                         ));

//next is to render the lists in the View, I tried with ViewBag instead.
 ViewBag.generalList = generalList2;
                return View(generalList2);

查看:

<table @*class="table table-striped table-responsive"*@ id="myTable" class="tablesorter" cellspacing="1">
    <thead>
        <tr>
            <th>
               Name
            </th>
            <th>
               Scheduled Arrival Time
            </th>
            <th>
                Arrival Time
            </th>
                Late Mins
            <th>
                Fine Imposed
            </th>
            <th>
               Scheduled Departure Time
            </th>
            <th>
               Departure Time
            </th>
            <th>
               TimeSpent
            </th>
            <th>
               DateTime
            </th>
            <th>
                Action
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in @ViewBag.generalList)
        {
            foreach (var item2 in item.Item1)
            {
                <tr>
                    <td>
                        @item2
                    </td>

                    @foreach (var item3 in item.Item2)
                    {

                    <td>
                        @item3
                    </td>
                    }

                    @foreach (var item4 in item.Item3)
                    {

                        <td>
                            @item4

                        </td>
                    }


                    @foreach (var item5 in item.Item4)
                    {

                        <td>
                            @item5
                        </td>
                    }

                    @foreach (var item6 in item.Item5)
                    {

                        <td>
                            @item6

                        </td>
                    }

                    @foreach (var item7 in item.Item6)
                    {

                        <td>
                            @item7

                        </td>
                    }

                    @foreach (var item8 in item.Item7)
                    {

                        <td>
                            @item8
                        </td>
                    }

                     @*<td>
                        <div class="btn-group btn-group-circle btn-group-sm btn-group solid">
                            @*<button type="button" class="btn blue" onclick="location.href='@Url.Action("Edit", "FineReport", new { id = item.CronID })'" style="">Edit &nbsp;<span class="glyphicon glyphicon-edit"></span></button>*@
                    @*<button type="button" class="btn green" onclick="location.href='@Url.Action("Details", "FineReport", new { id = item.CronID })'" style="">View &nbsp;<span class="glyphicon glyphicon-eye-open"></span></button>*@
                    @*<button type="button" class="btn red" onclick="location.href='@Url.Action("Delete", "FineReport", new { id = item.CronID })'" style="">Delete &nbsp;<span class="glyphicon glyphicon-trash"></span></button>
                            </div>
                        </td>*@

                </tr>
            }

        }
    </tbody>
</table> 

现在上面视图中的 sn-p 非常混乱,因为它没有按预期呈现列表。我尝试了不同的&lt;tr&gt; 方法来获取所有杂乱的记录(主要是冗余条目)。列表generalList2 有 7 个不同的列表,每个列表具有不同数量的元素(在本例中为项目)。

更新:继续彼得的建议,我采用了 Viewmodel 方法,如下所示;

public class Agenda
{

    public IList<string> Names { get; set; }
    public IList<TimeSpan> ArrivalTimes { get; set; }
    public IList<int> Fines { get; set; }
    public IList<TimeSpan> ArrList { get; set; }
    public IList<int> MinList { get; set; }
    public IList<TimeSpan> Departures { get; set; }
    public IList<TimeSpan> TimesSpent { get; set; }
}

控制器:

public ActionResult Index(int? EnrollNumber, DateTime? StartDate, DateTime? EndDate)
        {
 var empId = db.Employees.Where(x => x.EnrollNumber == EnrollNumber.ToString()).Select(x => x.EmployeeId);

                var getLoggedID = SessionManager.CurrentUser.EmployeeId;
                var dept = db.Departments.Where(x => x.LeadBy == SessionManager.CurrentUser.EmployeeId).FirstOrDefault();

                var teams = db.Teams.Where(x => x.DeptID == dept.DepartmentId);

                List<Employee> refinedEmpList = new List<Employee>();
                var empList = db.Employees.ToList();
                foreach (var v in teams)
                {
                    foreach (var c in empList)
                    {
                        if (v.TeamID == c.TeamId)
                        {
                            refinedEmpList.Add(c);
                        }
                    }
                }
                if (EnrollNumber != null && StartDate != null && EndDate != null)
                {
                    foreach (var emp in refinedEmpList)
                    {
 agenda.Add(completeStats(Convert.ToInt32(emp.EnrollNumber), StartDate.Value, EndDate.Value));


                    }
                }
                else
                {
                    foreach (var emp in refinedEmpList)
                    {
                        DateTime now = DateTime.Now;
                        var startDate = new DateTime(now.Year, now.Month, 1);
                        var endDate = now.Date;
   agenda.Add(completeStats(Convert.ToInt32(emp.EnrollNumber), startDate, endDate));



                    }
                }
 return View(agenda);   

查看:

<h2>Late Fine Report</h2>
@{
    int sum = 0;
 }

<table id="myTable" class="tablesorter" >
    <thead>
        <tr>
            <th>
                Name
            </th>
 <th>
                Total Fine
            </th>
            <th>
                Action
            </th>
        </tr>
    </thead>
    <tbody>

        @foreach (var agenda in Model)
        {
            if (agenda.Fines.Contains(0))
            {
                continue;
            }

            sum += agenda.Fines.Sum();
                <tr>

                    <td>
                        @Html.DisplayFor(modelItem => agenda.Names)
                    </td>
 <td>
                        @Html.DisplayFor(modelItem => agenda.Fines)
                    </td>
 <td>


                    <div class="btn-group btn-group-circle btn-group-sm btn-group solid">

    </div>
                                    </td>
                 </tr>

            }
        <tr>
            <td>
               <b> Total </b>
            </td>
            <td>
                <b> @sum</b>
            </td>
            <td>

            </td>
              </tr>
            </tbody>
    </table>

 <script>
        $(document).ready(function () {
            $("#myTable").tablesorter();
        }
    );
    </script>
<script>
        $(function () {

            var start = moment().subtract(29, 'days');
            var end = moment();

            function cb(start, end) {
                $('#reportrange span').html(start.format('MMMM D, YYYY') + ' - ' + end.format('MMMM D, YYYY'));
            }

            $('#reportrange').daterangepicker({
                startDate: start,
                endDate: end,
                ranges: {
                    'Today': [moment(), moment()],
                    'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
                    'Last 7 Days': [moment().subtract(6, 'days'), moment()],
                    'Last 30 Days': [moment().subtract(29, 'days'), moment()],
                    'This Month': [moment().startOf('month'), moment().endOf('month')],
                    'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
                }
            }, cb);

            cb(start, end);

        });

    </script>
 <script>
        function onSubmit(){
            var baseUrl = '@Url.Content("~/")';
            id = $('.selected-item').val();
            if(id == null || id == ""){
                console.log("enroll null");
                id = @Session["currentEmpID"].ToString();
                console.log("after enroll null: " + id);
            }
            console.log("Dropdown enroll: " + id);
            var x = document.getElementById("reportRange").innerText;
            s = $("#startDate").val();
            e = $("#endDate").val();

            var res = x.split("-");


            a = res[0], b = res[1];

            var sDate = new Date(a);
            var eDate = new Date(b);

            s = (sDate.getMonth() + 1) + '/' + sDate.getDate() + '/' + sDate.getFullYear();
            e = (eDate.getMonth() + 1) + '/' + eDate.getDate() + '/' + eDate.getFullYear();
            console.log("Fine CompStats SS: " + s);
            console.log("Fine CompStats EE: " + e);



            if (s == null && e == null)
            {
                // Return today's date and time
                var currentTime = new Date()

                // returns the month (from 0 to 11)
                var month = currentTime.getMonth() + 1

                // returns the day of the month (from 1 to 31)
                var endingDay = currentTime.getDate()

                // returns the year (four digits)
                var year = currentTime.getFullYear()

                var s1 = new Date(year, month - 1, 1); //Thu Feb 01 2018 00:00:00 GMT+0500 (Pakistan Standard Time)

                s1.getMonth() + 1  // 01
                s1.getDate()     // 02
                s1.getFullYear() // 2018

                console.log("starting date: " + s1);

                var s = (s1.getMonth() + 1) + "/" + s1.getDate() + "/" + s1.getFullYear();   //behtreen cheypi
                console.log("starting date: " + s);
                //        var s = '2/01/2018';
                var e = '@DateTime.Today.Date';
            }



            console.log("compStat start: " + s);
            console.log("compStat end: " + e);


            $.ajax({
                url: baseUrl + 'FineReport/Index?EnrollNumber=' + id + '&StartDate=' + moment(s).format("YYYY-MM-DD") + '&EndDate=' + moment(e).format("YYYY-MM-DD"),
                contenttype: 'application/json',
                data: '',
                type: 'post'
            }).done(function (data) {
                //console.log('KKcurrent time:', data);
                console.log('lateRec ' + data);
            });
            //}, 1000);
        }
    </script>         

问题: 除了工作正常之外,问题在于它每次都显示相同的数据,即使我从daerangepicker 中选择startDateendDate,有趣的是当在浏览器上检查控制台时实际上根据所选日期范围显示数据而不是视图,为什么?附图如下:

场景1:(默认加载索引时,没有给出日期,所以显示月份报告)

enter image description here

场景 2:现在,当我给出 3 月 12 日 - 3 月 14 日的日期范围时,它会显示相同的结果,但如果您在控制台中看到它,它会返回预期的结果 enter image description here

【问题讨论】:

  • 反对者?请解释一下我可以如何改进我的问题。
  • 我知道这不是 codereview,但我可以建议您首先将 Tuple 的使用更改为使用更具描述性的自定义类吗?当您查看视图时,您不知道 item1/2/3/... 的实际含义。这至少使您的代码更具可读性,并使我们更容易识别您的问题。
  • @Peter 我知道 Items 的顺序,Item1 是字符串列表,Item2 是 TimeSpan 列表,Item3 也是 TimeSpan 列表等等......正如它在 var generalList2 = new List&lt;Tuple&lt;List&lt;string&gt;, List&lt;TimeSpan&gt;, List&lt;TimeSpan&gt;, List&lt;int&gt;, List&lt;int&gt;, List&lt;TimeSpan&gt;, List&lt;TimeSpan&gt;&gt;&gt;(); 声明的那样
  • 是的,您知道,因为您刚刚编写了代码。但如果你一年后再看这段代码,你就不会再看了。你必须去控制器看看是什么。不试图判断,只是在这里提供帮助。我的想法是,如果您首先通过摆脱元组来重构代码,您可能会解决自己的问题,因为我觉得目前它正在使问题变得模糊。
  • @Peter 我很感激,但我没有看到任何其他方法可以传递这些多个列表并将它们显示在视图中,我应该添加屏幕截图以进一步澄清问题吗?

标签: javascript c# asp.net-mvc list tuples


【解决方案1】:

Peter 已经给出了一条更好的路径,转到已编辑的问题;有两种方法可以解决这个问题。

问题是;

您没有在应用最新数据之前清除模型表 这就是为什么它坚持旧的原因

在你的OnSubmit();

<script>
        function onSubmit(){
            var baseUrl = '@Url.Content("~/")';
            id = $('.selected-item').val();
            if(id == null || id == ""){
                console.log("enroll null");
                id = @Session["currentEmpID"].ToString();
                console.log("after enroll null: " + id);
            }
            console.log("Dropdown enroll: " + id);
            var x = document.getElementById("reportRange").innerText;
            s = $("#startDate").val();
            e = $("#endDate").val();

            var res = x.split("-");


            a = res[0], b = res[1];

            var sDate = new Date(a);
            var eDate = new Date(b);

            s = (sDate.getMonth() + 1) + '/' + sDate.getDate() + '/' + sDate.getFullYear();
            e = (eDate.getMonth() + 1) + '/' + eDate.getDate() + '/' + eDate.getFullYear();
            console.log("Fine CompStats SS: " + s);
            console.log("Fine CompStats EE: " + e);



            if (s == null && e == null)
            {
                // Return today's date and time
                var currentTime = new Date()

                // returns the month (from 0 to 11)
                var month = currentTime.getMonth() + 1

                // returns the day of the month (from 1 to 31)
                var endingDay = currentTime.getDate()

                // returns the year (four digits)
                var year = currentTime.getFullYear()

                var s1 = new Date(year, month - 1, 1); //Thu Feb 01 2018 00:00:00 GMT+0500 (Pakistan Standard Time)

                s1.getMonth() + 1  // 01
                s1.getDate()     // 02
                s1.getFullYear() // 2018

                console.log("starting date: " + s1);

                var s = (s1.getMonth() + 1) + "/" + s1.getDate() + "/" + s1.getFullYear();   //behtreen cheypi
                console.log("starting date: " + s);
                //        var s = '2/01/2018';
                var e = '@DateTime.Today.Date';
            }



            console.log("compStat start: " + s);
            console.log("compStat end: " + e);


            $.ajax({
                url: baseUrl + 'FineReport/Index?EnrollNumber=' + id + '&StartDate=' + moment(s).format("YYYY-MM-DD") + '&EndDate=' + moment(e).format("YYYY-MM-DD"),
                contenttype: 'application/json',
                data: '',
                type: 'post'
            }).done(function (data) {
                //console.log('KKcurrent time:', data);
                console.log('lateRec ' + data);
            });
            //}, 1000);
        }
    </script>  

1) 返回一个 json 对象,而不是控制器内的模型视图,它将为您提供最新的表数据。

2) 在上面的视图中,用&lt;div&gt; 包裹表格;

div id="tableContainer">
    <table id="myTable" name="myTable" class="tablesorter">
//
</div> 

然后在脚本中进行修改;

 $('#myTable').html('');

            $.ajax({
                url: baseUrl + 'FineReport/Index?EnrollNumber=' + id + '&StartDate=' + moment(s).format("YYYY-MM-DD") + '&EndDate=' + moment(e).format("YYYY-MM-DD"),
                contenttype: 'application/json',
                data: '',
                type: 'post'
            }).done(function (data) {
 var result = $(data).find('#tableContainer');
 $('#tableContainer').html(result);

            });

这将找到选定的元素并将其附加到表格中,注意我在使用 ajax 之前清除了表格;

$('#myTable').html('');

【讨论】:

    【解决方案2】:

    首先,像这样使用 Tuple 基本上是在避免创建自定义类。我可以建议您在项目中创建一个新模型:/Models/Agenda.cs 看起来像这样:

    public class Agenda {
        public IList<string> Names {get;set;}
        public IList<TimeSpan> ArrivalTimes {get;set;}
        public IList<int> Fines {get;set;}
        public IList<TimeSpan> ArrList {get;set;}
        public IList<int> MinList {get;set;}
        public IList<TimeSpan> Departures {get;set;}
        public IList<TimeSpan> TimesSpent {get;set;}
    }
    

    现在在您的视图中,您可以指定视图的模型是此类的列表:

    @model IList<Agenda>
    

    然后您可以从控制器中调用您的视图:

    return View(myListOfAgendas)
    

    无需使用 ViewBag。 现在您可以使用属性“模型”访问视图内的模型。 举个小例子:

    <table>
    @foreach(var agenda in Model){
        <tr>
            ....
        </tr>
    }
    

    但正如我在 cmets 中提到的那样。我知道这不是您问题的答案,但我认为如果您像这样重构代码,您会更容易理解。

    【讨论】:

    • 是的,是的,皮特。让我采用这种方法。
    • 祝你好运,让我知道进展如何!
    猜你喜欢
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多