【问题标题】:Partial refresh in ASP using ajax使用 ajax 在 ASP 中进行部分刷新
【发布时间】:2016-02-25 21:01:54
【问题描述】:

如何在 cshtml 中使用 Ajax 对页面进行部分刷新?

据我了解,Ajax 是必需的。在我的场景中,在我的索引页面中,我有一个表,其中每一行都有一个程序(一个批处理文件)和一个运行按钮。在桌子下面我有一个用于程序输出的空间。我希望无需刷新页面的其余部分即可填充(我很高兴等待程序刚刚完成)。

代码如下,但总的来说,我有一个用于表格数据的模型,一个用于所选程序日志/输出的模型。索引页面的控制器创建两者并将它们传递给视图模型,该视图模型被传递给视图。当点击 Run 按钮时,控制器中的 Index 重载方法处理程序的运行并“获取”输出。它还会在 VM 中填充适当的模型(可能并不理想,我愿意接受改进它的建议)。

重载的方法当前返回一个 PartialViewResult 并且输出/日志记录有它自己的 PartialView(因为我想在其他地方重用它)。这也是为什么它有一个单独的模型。在 PartialView 中打断点,但在浏览器的页面上没有出现。

我正在使用带有 Razor 的 ASP.NET-MVC-4。

查看(索引.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>
}

脚本日志

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

视图模型

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);
    }

【问题讨论】:

    标签: asp.net ajax asp.net-mvc-4


    【解决方案1】:

    由于您正在创建 $.post(),因此您需要使用 [HttpPost] 装饰您的 /UpdateTest/Run 操作。

    您也没有定义成功处理程序,因此,当您发出请求时,您永远不会对它做任何事情。

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

    【讨论】:

    • 感谢@Jasen,您的 ajax 代码修复了它。我也意识到我没有用日志结果更新虚拟机,所以我也修复了这个问题。奇怪的是我不需要HttpPost 属性,但无论如何我已经添加了它。
    • 对不起,我说得太早了,更新不起作用。我为断点多打了一次 F5,不小心刷新了整个页面。此时日志存在,因此显示出来。我还尝试在 $("#log") 行之前添加一个警报(...),但我从来没有看到警报,就好像它甚至没有进入 Ajax
    • 那么你需要检查错误处理程序和浏览器的网络监视器以获取有关错误的更多信息。
    • 据我所知,它甚至没有进入 ajax,通过添加 ajax .always(function () { alert(NAME) }) 永远不会产生警报. (抱歉更新延迟-我在度假)
    • 这些是否嵌入到表单中?如果是这样,您需要阻止默认提交。使用网络监视器查看请求并检查标头以查看您正在发送 XMLHttpRequest (AJAX)。
    【解决方案2】:

    在@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] 属性

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多