2015-11-23 2 views
0

Как вы частично обновляете страницу с помощью Ajax в cshtml?Частичное обновление в ASP с использованием ajax

Как я понимаю, требуется Ajax. В моем сценарии на моей индексной странице у меня есть таблица, в которой каждая строка имеет программу (пакетный файл) и кнопку «Запуск». Под таблицей у меня есть место для выхода программы. Я бы хотел, чтобы это было заполнено (я рад дождаться завершения программы только сейчас), не обновляя остальную часть страницы.

Код приведен ниже, но в целом у меня есть одна модель для данных таблицы, одна модель для выбранного журнала/выхода программы. Контроллер для индексной страницы создает оба и передает их в модель представления, которая передается в представление. Когда нажата кнопка «Run», метод перегрузки Index в контроллере обрабатывает запуск программы и «получение» вывода. Он также заполняет соответствующую модель в VM (возможно, не идеально, и я открыт для предложений по ее улучшению).

Перегруженный метод в настоящее время возвращает PartialViewResult, а выход/запись имеет собственный PartialView (поскольку я захочу его повторно использовать в другом месте). Вот почему у него есть отдельная модель. В точках разбивки PartialView попадают, но они не отображаются на странице в браузере.

Я использую ASP.NET-MVC-4 с Razor.

View (Index.cshtml)

<script src="https://code.jquery.com/jquery-1.10.2.js"></script> 
@model ViewModels.UpdateTestViewModel 
@{ ViewBag.Title = "Update Test"; } 
@{ 
    <table> 
     @* Headers *@ 
     <tr> 
      <td>Programs</td> 
     </tr> 

     @* Data *@ 
     <tr> 
      <td>@Model.ProgramName</td> 
      <td style="min-width:75px"><input id="btnRun" type="button" value="Run" /></td> 
     </tr> 
    </table> 

    <div id="log"> 
     @Html.Partial("ScriptLog", Model.Log) 
    </div> 

    <script> 
     $("input[type=button]").on("click", function() { 
      var NAME = ($(this).parent().siblings(":first")).text(); 
      $.post("/UpdateTest/Run", { input: NAME }); 
     }); 
    </script> 
} 

Частичный вид

@model Models.ScriptLog 
@if (Model != null && Model.Log.Any(x => !string.IsNullOrWhiteSpace(x))) 
{ 
    <fieldset> 
     <legend>Log</legend> 
     @foreach (string entry in Model.Log) 
     { 
      <p>@entry</p> 
     } 
    </fieldset> 
} 

Script Log

public IEnumerable<string> Log { get { // returns log } } 

ViewModel

public class UpdateTestViewModel 
{ 
    public string ProgramName { get { return "My Program"; } } 

    public ScriptLog Log { get { return _log; } } 
    private readonly ScriptLog _log; 

    public UpdateTestViewModel(ScriptLog log) 
    { 
     _log = log; 
    } 
} 

Контроллер

public ActionResult Index() 
    { 
     if (SessionFacade.CurrentUpdateTestLog == null) 
     { 
      ScriptLog log = new ScriptLog(); 
      SessionFacade.CurrentUpdateTestLog = log; // Store in Session 
     } 

     UpdateTestViewModel vm = new UpdateTestViewModel(SessionFacade.CurrentUpdateTestLog); 

     return View(vm); 
    } 

    [ActionName("Run")] 
    public PartialViewResult Index(string input) 
    { 
     ExecuteScript.ExecuteUpdateTestScript(input); // Run batch file 
     UpdateTestLog(input); // Get log and update in Session 

     return PartialView("ScriptLog", SessionFacade.CurrentUpdateTestLog); 
    } 

ответ

1

Поскольку вы делаете $.post() вам нужно украсить ваш /UpdateTest/Run действие с [HttpPost].

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

$.post("/UpdateTest/Run", { input: NAME }) 
    .done(function(partialResult) { 
     $("#log").html(partialResult); 
    }) 
    .fail(function(jqxhr, status, error) { 
     console.log(jqXhr, status, error); 
    }); 
+0

Спасибо @Jasen, ваш код ajax исправил его. Я также понял, что я не обновлял VM с результатами журнала, поэтому я тоже это исправил. Любопытно, что мне не нужен атрибут «HttpPost», но я добавил его в любом случае. –

+0

Извините, я говорил слишком рано, обновление не работает. Я ударил F5 дополнительное время для контрольных точек и случайно обновил всю страницу. В этот момент журнал присутствует, и поэтому он отображается. Я также попытался добавить предупреждение (...) перед строкой $ ("# log"), и я никогда не вижу предупреждения, это похоже на то, что он даже не попадает в Ajax –

+0

. Затем вам нужно проверить обработчик ошибок и сетевой монитор браузера, чтобы получить дополнительную информацию об ошибке. – Jasen

0

С большой помощью и терпения от @Jasen я получил рабочее решение, которое должно было расширить существующий Ajax, так что она выглядит следующим образом:

$("input[type=button]").on("click", function() { 
    var NAME = ($(this).parent().siblings(":first")).text(); 
    $.post("/UpdateTest/Run", { input: NAME }) 

    .done(function (partialResult) { 
     $("#log").html(partialResult); 
    }) 
}); 

Примечание Я также добавил атрибут [HttpPost] в контроллер

Смежные вопросы