mvc 5在回发后启动javascript定时器

mvc 5 start javascript timer after postback

本文关键字:启动 javascript 定时器 mvc      更新时间:2023-09-26

我是MVC的新手,所以我认为我做错了,但我似乎无法理解这一点。我有一个小的网络应用程序,用来跟踪花在项目上的时间。网络表单版本只有一个更新面板,面板上有几个文本框和一个按钮,下面是一个网格&中继器显示项目的id和amp;日期其中一个文本框允许我输入项目编号,然后按钮启动计时器,计时器将显示在第二个文本框中。按钮文本在启动/停止之间切换。

web表单版本使用PRG模式,因此如果我单击刷新,它将不会执行另一次POST。所以点击按钮可以节省我的开始时间&项目到数据库,然后重定向到我使用RegisterStartupScript触发计时器的同一页面。这里需要注意的是,如果js函数正在运行,我需要将运行项目的当前开始时间传递给它,否则我将传递null。

我一直在思考如何在MVC中以同样的方式实现这一点。没有更新面板,我认为整个视图正在刷新,因为我可以看到计时器立即启动(显示00:00:01),但随后文本框变为空白。现在,我的两个文本框&按钮在Ajax.BeginForm中,其余数据在局部视图中。我也知道AjaxHelper是不推荐使用的,所以我想知道如何使用jQuery实现同样的功能。

这是我的控制器:

    [HttpGet]
    public ActionResult Index()
    {
        LoadDic(false);
        VerifyDic();
        return View(db.GetAll().ToList());
    }
    [HttpPost]
    public ActionResult Index(FormCollection values)
    {
        var project = values["ProjectDescTextBox"];
        ViewData["ProjectText"] = project; 
        ViewData["ServerButtonText"] = "Start";
        if (string.IsNullOrEmpty(project)) 
            return View(db.GetAll().ToList());
        // this removes the milliseconds...
        var dt = new DateTime((DateTime.Now.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);
        //TODO: make sure we're getting today's entry...
        var existing = db.GetAll().FirstOrDefault(t => t.Project == project);
        if (existing != null)
        {
            if (existing.TotalSeconds.HasValue)
            {
                if (existing.StartTime < existing.EndTime)
                    existing.StartTime = dt;
                else
                {
                    existing.EndTime = dt;
                    existing.TotalSeconds = existing.TotalSeconds + Convert.ToInt32(Math.Floor(dt.Subtract(existing.StartTime.Value).TotalSeconds));
                }
            }
            // if total seconds is null, this is the first time we've stopped; get start time, add time span, update record
            else
            {
                existing.EndTime = dt;
                existing.TotalSeconds = Convert.ToInt32(Math.Floor(dt.Subtract(existing.StartTime.Value).TotalSeconds));
            }
            Edit(existing);
        }
        else
        {
            existing = new TimeEntry { Project = project, StartTime = DateTime.Now };
            Create(existing);
        }
        return View(db.GetAll().ToList());
    }

这是我的观点:

@section Javascript
{
    <script type="text/javascript" src="@Url.Content("/Scripts/Timer.js")"></script>
}

@using (Ajax.BeginForm("Index", "TimeTracker", new AjaxOptions { HttpMethod = "POST"  }))
{
    @Html.AntiForgeryToken()
    @Html.TextBox("ProjectDescTextBox", @ViewData["ProjectText"], new { @class = "TextBox" })
    <input type="text" id="htmlTimer" class="TextBox" />
    <input id="ServerButton" type="submit" class="Button" value='@ViewData["ServerButtonText"]' onclick='doTimer(@ViewData["CurrentStartTime"]);' />
}
@Html.Partial("GridDataPartialView")

如果计时器不在表单中,它本身工作得很好,但当我单击开始按钮时,我不会得到我的项目值。

有人能看到这有什么问题吗?或者我需要做些什么才能让计时器在客户端上运行?我确信有一种方法可以点击一个按钮,在服务器上做一些工作(即保存到数据库),并将一些数据发送回客户端以启动计时器,我似乎无法同时做到这两点;我可以保存数据,也可以启动计时器。

如有任何帮助,我们将不胜感激。

你试过这样的东西吗?

@using (Ajax.BeginForm("Index", "TimeTracker", new AjaxOptions { HttpMethod = "POST", OnSuccess="return function() {doTimer('" + ViewData["CurrentStartTime"] + "');}()"  }))
{
    @Html.AntiForgeryToken()
    @Html.TextBox("ProjectDescTextBox", @ViewData["ProjectText"], new { @class = "TextBox" })
    <input type="text" id="htmlTimer" class="TextBox" />
    <input id="ServerButton" type="submit" class="Button" value='@ViewData["ServerButtonText"]'  />
}

您可能需要稍微调整一下成功率