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

时间:2014-04-24 14:54:06

标签: javascript jquery timer asp.net-mvc-5

我是MVC的新手,所以我假设自己错了,但我似乎无法理解这一点。我有一个小型Web应用程序,用于跟踪项目工作时间。 Web表单版本只是具有几个文本框和一个按钮的更新面板,并在其下面一个网格&转发器以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")

如果计时器本身不在表单内部,那么它本身可以正常工作,但是当我点击开始按钮时,我没有将我的项目值发回。

任何人都可以看到这个或我需要做些什么来保持计时器在客户端上运行?我确定有一种方法可以点击一个按钮,在服务器上做一些工作(即保存到数据库),并将一些数据发送回客户端以启动计时器,我似乎无法同时工作;我可以保存数据 - 或 - 启动计时器。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

你尝试过这样的事吗?

@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"]'  />
}

您可能需要稍微调整onsuccess