这个问题没有完全回答,请随意捐款!
我正在尝试在提交大型表单时显示简单的progress bar
该表单包含十几个字段,以及一些文件上载字段,用户可以在其中选择图片。然后,当他点击Create
按钮时,会提交包含数据和图片的表单,并在DB中创建实体。 (只需点击一下即可提交表格和图片)
一切正常,但我想在提交过程中显示进度条
我发现很多教程解释了如何显示进度条,但我没有找到任何人解释如何显示进度条,指示方法完成的工作百分比,即我希望在提交过程中看到10%,25%等等。
所以,基本上,这就是我所做的:(这是一个ASP.NET MVC3项目)
@model MyModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "target-form", enctype = "multipart/form-data" }))
{
//some Html.TextBoxFor() and other @Html.DropDownListFor
@Html.TextBoxFor(m => m.File, new { type = "file"})
<input type="submit" value="Create" class="submitButton" />
<div id="progressBar"></div>
}
一个基本的控制器
[HttpPost]
public ActionResult Create(MyModel model)
{
if (ModelState.IsValid)
{
DALLayer dal = new DALLayer()
dal.AddEntity(model);
return RedirectToAction("Index", "Home");
}
return null;
}
是否可以转换显示上传进度状态的<div>
中的上一个progressBar
?
以下是我的要求:
非常感谢你 !
更新1
这是一个JSFIDDLE,我正在尝试调整this link,但没有成功......如果您认为可以提供帮助,那么欢迎您!
更新2
好的,我用acarlon's answer提交了我的表单XMLHttpRequest
,数据正确地发布到控制器。但是,ProgressBar仍然没有出现!
我只需通过以下方式替换传递给控制器的数据:
formData = new FormData(document.getElementById("target-form") );
xhr.open("POST", "@Url.Action("MyMethod", "MyController")", true );
并尝试一些不同的标题,例如:
xhr.setRequestHeader("X-File-Name", $('#Files_0__File')[0].files[0].name);
xhr.setRequestHeader("X-File-Size", $('#Files_0__File')[0].files[0].size);
xhr.setRequestHeader("X-File-Type", $('#Files_0__File')[0].files[0].type);
//Also tried with "Content-Length" but it doesn't care about it.
(这里硬编码以确保它具有良好的价值。我会在循环中完成它,因为我会更放心。)
当我提交表单时,XMLHttpRequest
发送包含以下字段:
readyState:4
状态:0&lt; =应该是200,对吗?
在error handler
中,我有以下值:
已加载:0
总数:883526
键入:“错误”
所以数据会提交给我的控制器,但是我无法显示这个该死的进度条......
答案 0 :(得分:4)
您可以使用XMLHttpRequest
在上传文件时接收更新。还有各种jquery类型的包装器来实现相同的功能。我将使用XMLHttpRequest
描述解决方案。
首先拦截表单提交。
$("#target-form").submit(function () {
然后创建XHR请求:
xhr = new XMLHttpRequest();
然后注册以获得有关进度事件的通知:
xhr.upload.addEventListener( "progress", function ( evt )
{
if( evt.lengthComputable )
{
var progressPercent = ( evt.loaded / evt.total ) * 100;
showProgress( value );//your function.
}
}, false );
//Some other events you will probably want to subscribe to
xhr.addEventListener( "load", function ()
{
fileUploadComplete( this.responseText );
}, false );
xhr.addEventListener( "error", function ( first, second, third )
{
fileUploadComplete( "Error: Image format not supported." );
}, false );
xhr.addEventListener( "abort", function ()
{
fileUploadComplete( "Error: Upload was cancelled. Please try again." );
}, false );
打开XHR传入任何参数(id
显示为示例)
xhr.open( "post", '@Html.Raw( @Url.Action( "UploadImage", new { someId = id } ) )', true );
// Set appropriate headers
xhr.setRequestHeader( "Content-Type", "multipart/form-data" );
xhr.setRequestHeader( "X-File-Name", name );
// Send the file
xhr.send( file );
然后在控制器中:
public ActionResult UploadImage( int someId, HttpPostedFileBase userFile )
{
...
}
您将在更新处理程序中收到更新。
长时间运行的服务器任务的扩展
如果服务器上有一些长时间运行的任务(例如将数据写入数据库),则需要在服务器上对操作进行分块(以便在完成每个块时提供更新)并实现代码处理可以从javascript查询的长时间运行的服务。见here。基本思想是在服务器端启动任务,并定期检查Javascript的进度。您可能希望有两个单独的进度条,一个用于上载,另一个用于服务器端操作。这为用户提供了更多信息 - 他们将知道文件上传已完成,现在正在进行一些服务器端操作。
答案 1 :(得分:2)
添加一个ajax定时器控件,用于检查服务器的进度并设置时间间隔(比如每2秒)。
在新线程上执行服务器任务。这将导致您的帖子在后台执行长任务时立即返回。启动ajax计时器。
当长任务工作时,让它更新一个包含完成的%工作的会话变量。
当计时器回发到服务器时,从会话变量中获取完成的%工作。
您可以通过设置内部div和外部div来设计进度条。将内部div的宽度设置为完成的%工作:$('#progressBarWorkDone')。css('width',WorkDone +'%');
<div id="progressBar" style="width:400px;">
<div id="progressBarWorkDone" style="width:0px;height:10px;background-color:red;"><div/>
<div/>
注意,如果您不知道如何使用计时器控件,您还可以使用setInterval(function(){AJAX CALLBACK GOES HERE},1000)从javascript执行AJAX调用;
然而,已经说过所有这一切只是简单地将动画gif放在进度条div中。隐藏div,然后在单击提交按钮时显示div。
<input type="submit" onclick="$('#progressBar').show();" value="Create" class="submitButton" />
<div id="progressBar" style="display:none;"><img src="myProgressBar.gif" /></div>
答案 2 :(得分:-2)
我曾经使用带有perl后端文件的SWF上传器(当时PHP没有支持上传进程),但看起来它已不再处于活跃开发状态了。
我还没有使用Plupload,但它看起来非常适合你。好像你可以拥有asp backend。
祝你好运并保持干爽;)