我有一个很长的数据库网络调用,我想分块填充我的模型。我们正在谈论 asp.net MVC。 我有一个模糊的想法,每次有新的 block 可用时,我应该触发 model.Bind() 但我不知道如何在之间进行管道
a)以 block 的形式提供数据的服务 - 它是使用事件模式实现的 - 每次有新 block 可用时都会触发一个事件,但是哪个事件?它应该包含对模型的引用?
b)将绑定(bind)到模型的数据(我想它不应该是一个bind(),而是对某个集合的添加)
c) 如果步骤 a 和 b 中一切正常,那么更改将传播到 View ,而无需进一步执行操作?
最佳答案
您可以使用long polling使用隐藏的 iframe 和来自服务器的分块传输编码,它将吐出 <script>
当数据可用时进行标记。在此脚本标记中,您可以调用自定义回调 JavaScript 函数,该函数将负责格式化结果。
更新:
根据评论部分的要求,这里是使用隐藏 iframe 的长轮询技术的示例实现。
假设您有一些模型:
public class MyViewModel
{
public string Foo { get; set; }
}
并且您有一个服务以 block 的形式返回此模型,并使用事件通知调用者 block 可用:
public class MyService
{
public void GetModels(Action<MyViewModel, object> onModelAvailable, object state, Action onComplete)
{
Task.Factory.StartNew(x =>
{
try
{
for (int i = 0; i < 10; i++)
{
onModelAvailable(new MyViewModel
{
Foo = "foo " + i
}, x);
Thread.Sleep(1000);
}
}
finally
{
onComplete();
}
}, state);
}
}
现在,我们可以拥有以下 Controller :
public class HomeController : AsyncController
{
public ActionResult Index()
{
return View();
}
public ActionResult LongPoll()
{
var service = new MyService();
return new MyActionResult(service);
}
}
以及以下 View :
<script type="text/javascript">
// we define a callback function which will be invoked
// when a chunk is available from the server
var callback = function (model) {
// the model variable passed here will represent the chunk
$($('<div/>', {
html: model.Foo
})).appendTo('#result');
};
</script>
<iframe style="display:none;" src="@Url.Action("longpoll")"></iframe>
<div id="result"></div>
现在当然的最后一部分是自定义操作结果的实现,它将执行分块传输:
public class MyActionResult : ActionResult
{
private readonly MyService _service;
public MyActionResult(MyService service)
{
_service = service;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.BufferOutput = true;
response.ContentType = "text/html";
var wait = new ManualResetEvent(false);
_service.GetModels((model, state) =>
{
var httpResponse = (HttpResponseBase)state;
httpResponse.BufferOutput = true;
httpResponse.ContentType = "text/html";
var serializer = new JavaScriptSerializer();
var script = string.Format(
"<script type=\"text/javascript\">window.parent.callback({0});</script>",
serializer.Serialize(model)
);
httpResponse.Write(script);
httpResponse.Flush();
},
response,
() =>
{
wait.Set();
});
wait.WaitOne();
}
}
关于c# - 逐步更新 ASP.NET MVC 中的模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8896817/