Отображение вида в середине контроллера MVC3 - PullRequest
0 голосов
/ 07 марта 2012

Я бы хотел несколько раз прошить представление в контроллере.

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

Требуется много времени для расчета данных, и я хотел бы отображать вид с шагом.

Ответы [ 2 ]

1 голос
/ 07 марта 2012

Вы не можете так делать. Ничего не отправляется в браузер, пока представление не будет отображено, и это происходит после того, как вы вернете представление из контроллера.

Если вы хотите, чтобы страница отображалась во время вычисления данных, вы должны сделать это в двух или более запросах. Сначала отобразите простую страницу без данных, затем отправьте запросы AJAX на сервер, где вы рассчитываете данные, и вернитесь к сценарию, который будет отображаться на странице.

0 голосов
/ 07 марта 2012

Это похоже на работу для небольшого количества ajax и некоторого переосмысления того, как ваша работа будет выполняться.

обо всем по порядку, покажите свое мнение. Я бы поместил это в свой собственный контроллер, где пользователь может запрашивать задачи

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

Далее я бы создал еще один контроллер для работы с методами, которые добавляют задачу и возвращают частичный результат

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>

Надеюсь, это приведет вас туда, где вы хотите быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...