在MVC3控制器中间显示视图

时间:2012-03-06 23:08:58

标签: .net asp.net-mvc-3

我想在控制器中多次闪现视图。

public ActionResult MyController()
{
    ViewBag.Data=CalculateSomeData();
    ShowView();
    ViewBag.Data+=CalculateMoreData();
    ShowView();
    ViewBag.Data+=CalculateExtraData();
    return View();
}

计算数据需要很长时间,我想以增量显示视图。

2 个答案:

答案 0 :(得分:1)

你不能这样做。在呈现视图之前,不会向浏览器发送任何内容,并且在从控制器返回视图后会发生这种情况。

如果您希望在计算数据时显示页面,则必须在两个或更多请求中执行此操作。首先显示没有数据的普通页面,然后向计算数据的服务器发出AJAX请求,并返回到要在页面中显示的脚本。

答案 1 :(得分:0)

这看起来像是一个ajax的工作,有些人正在重新思考你的工作将如何运作。

首先要显示您的视图我会将其放在自己的控制器中,用户可以在其中请求任务

public class RequestTaskController: Controller
{
   public ActionResult LongRunningAction()
   {
       return View();
   }
}

接下来,我将创建另一个Controller来处理添加任务并返回部分结果的方法

public class WorkController: Controller
{
   [HttpPost]
   public ActionResult CreateLongRunningTask(TaskRequestViewModel viewModel)
   {
       AddTask(viewModel);
       return CurrentTasks();
   }
}


public PartialViewResult AddTask(TaskRequestViewModel viewModel)
{
   // I'm using Session here because its easy
    var currentTasks = Session["tasks"] as ConcurrentDictionary<string, Task>??
                              new ConcurrentDictionary<string, Task>();

    Task task;
    if (!currentTasks.TryGetValue(viewModel.Key, out task))
    {
       task = new Task(); // what ever that is
       currentTasks.TryAdd(key, task);
    }

    // do stuff with task like change progess, add payload, mark as complete

}



public PartialViewResult CurrentTasks()
{
     ViewData.Model = Session["tasks"] as ConcurrentDictionary<string, Task>??
                              new ConcurrentDictionary<string, Task>();

    // do stuff with task like change progess, add payload, mark as complete

     return PartialView("_CurrentTasks");
}

部分View _CurrentTasks.cshtml将位于Views / Shared中,并列出您拥有的任务以及他们的最新进展。

 @using System.Collections.Concurrent
 @using Your.Models
 @model ConcurrentDictionary<string, Tasks>

<ul>
@if (Model.Count > 0)
{
   foreach (var task in Model)
    {
       <li>@:task</li>
    }
}
</ul>

因此,它会照顾它们。现在你希望你的LongRunningAction视图将它全部包装起来,所以在那里的某个地方你会想要做这样的事情。

<div id="currentTasks" />

<script type="text/javascript">

var interval;

function loadPartialView() {
    //Populate the contents of the placeholder with the result returned by the action method 
    $('#currentTasks').load('@Url.Action("CurrentTasks", "Work")', function () {
        // maybe do something to links
    });
}

$(function () {

    loadPartialView();

    interval = setInterval(loadPartialView, 5000);

});

</script>

希望能让你到达你想去的地方。