MVC3 - 在viewbag中压缩模型
我有一个 MVC3 视图,旨在为我们的客户运行报告。在允许您选择报告选项的视图中,我传递了大量客户列表(~3K)。我将其渲染如下:
@{Html.RenderPartial("_ClientSelector", ViewBag.Clients as IEnumerable<Client>);}
_ClientSelector 部分如下所示:
<select id="clients" class="clientList" multiple="multiple">
@foreach (Client client in Model) {
var prefix = client.Parent == null ? "" : String.Format("{0}-({1}) / ", client.Parent.Name, client.Parent.Id);
<option value="@client.Id">@[email protected](@client.Id)</option>
}
</select>
我正在使用 jQuery 多选库将其转变为漂亮的视觉显示。
我的问题是,是否可以在服务器端压缩此列表?到目前为止,此视图中最慢的部分是加载此客户端列表。在chrome中使用PageSpeed,它建议压缩html以使其加载速度更快,这可能吗?如果这需要在它自己的控制器操作中而不是将其放入 ViewBag 中,我不介意这样做。我只是想看看是否有办法可以加快此页面的速度。
编辑:
我开始使用下面的模板。当我手动构建 json 时,它可以工作。但是,当我尝试使用 $.getJSON 从服务器获取它时,它永远不会触发结果。使用 Chrome 中的调试工具,我看到返回的响应,它看起来像有效的 json。你能发现这有什么问题吗?
public ActionResult ClientList() {
var clients = reportRepository.GetClientList();
IList<object> model = new List<object>();
foreach (Phoenix.Models.Client c in clients) {
var prefix = c.Parent == null ? "" : String.Format("{0}-({1}) / ", c.Parent.Name, c.Parent.Id);
model.Add(new { value = c.Id.ToString(), text = String.Format("{0}{1}-({2})",prefix,c.Name,c.Id) });
}
return Json(model, JsonRequestBehavior.AllowGet);
}
在视图中:
<script type="text/javascript">
$(function () {
$.getJSON("/Report/ClientList", null, function (data) {
$("#templateOptionItem").tmpl(data).appendTo("#clients");
});
});
</script>
<script id="templateOptionItem" type="test/html">
<option value=\'{{= value}}\'>{{= text}}</option>
</script>
<select id="clients" class="clientList" multiple="multiple">
</select>
--这是使用 $.ajax 方法的另一次尝试,但它也不会在结果上触发
$.ajax({
url: "/Report/ClientList",
dataType: "json",
success: function (data) {
$("#templateOptionItem").tmpl(data).appendTo("#clients");
}
});
这是有效的示例:
var Clients = [{ value: 1, text: "test123" },
{ value: 2, text: "123test" }]
$("#templateOptionItem").tmpl(Clients).appendTo("#clients");
经过多次调整,我终于得到了一些工作:
$.ajax({
url: "/Report/ClientList",
dataType: "json",
complete: function (data) {
$("#templateOptionItem").tmpl(JSON.parse(data.responseText)).appendTo("#clients");
}
});
我仍然没有确定为什么它不会在成功事件上触发,但使用完整事件并在responseText上执行JSON.parse似乎已经成功了。
I have an MVC3 view that's design to run reports for our clients. In the View that lets you select the report options, I pass a large list of our clients (~3K). I'm rendering it like this:
@{Html.RenderPartial("_ClientSelector", ViewBag.Clients as IEnumerable<Client>);}
The _ClientSelector partial looks like this:
<select id="clients" class="clientList" multiple="multiple">
@foreach (Client client in Model) {
var prefix = client.Parent == null ? "" : String.Format("{0}-({1}) / ", client.Parent.Name, client.Parent.Id);
<option value="@client.Id">@[email protected](@client.Id)</option>
}
</select>
I'm using the jQuery multiselect library to turn this into a nice visual display.
My question is, is it possible to compress this list server side? By far, the slowest part of this view is loading this list of clients. Using PageSpeed in chrome, it suggests compressing the html to make it load faster, is that possible? If this needs to be in it's own controller action instead of putting it in the ViewBag, I don't mind doing that. I just want to see if there is a way I can speed this page up.
Edit:
I started playing around with the templates you have below. When I build json manually, it works. However when I try to get it from the server using $.getJSON, it never fires on the results. Using debug tools in Chrome, I see the response coming back, and it looks like valid json. Can you spot something wrong with this?
public ActionResult ClientList() {
var clients = reportRepository.GetClientList();
IList<object> model = new List<object>();
foreach (Phoenix.Models.Client c in clients) {
var prefix = c.Parent == null ? "" : String.Format("{0}-({1}) / ", c.Parent.Name, c.Parent.Id);
model.Add(new { value = c.Id.ToString(), text = String.Format("{0}{1}-({2})",prefix,c.Name,c.Id) });
}
return Json(model, JsonRequestBehavior.AllowGet);
}
And in the view:
<script type="text/javascript">
$(function () {
$.getJSON("/Report/ClientList", null, function (data) {
$("#templateOptionItem").tmpl(data).appendTo("#clients");
});
});
</script>
<script id="templateOptionItem" type="test/html">
<option value=\'{{= value}}\'>{{= text}}</option>
</script>
<select id="clients" class="clientList" multiple="multiple">
</select>
--This was another attempt using the $.ajax method, but it too does not fire on the results
$.ajax({
url: "/Report/ClientList",
dataType: "json",
success: function (data) {
$("#templateOptionItem").tmpl(data).appendTo("#clients");
}
});
This is the example that works:
var Clients = [{ value: 1, text: "test123" },
{ value: 2, text: "123test" }]
$("#templateOptionItem").tmpl(Clients).appendTo("#clients");
After much tweaking, I finally got something to work:
$.ajax({
url: "/Report/ClientList",
dataType: "json",
complete: function (data) {
$("#templateOptionItem").tmpl(JSON.parse(data.responseText)).appendTo("#clients");
}
});
I'm still not sure why it would not fire on the on the success event, but using the complete event and doing a JSON.parse on the responseText seems to have done the trick.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否考虑过将其作为 JSON 数据发送到视图并将其绑定到 客户端模板 或使用 淘汰赛。
您发送的数据大小大幅增加,因为您正在重复为每个 3k 客户端生成的相同 html。如果您在没有标记的情况下发送该内容,则大小会小得多,然后列表项的代码只能通过 json 数据的占位符发送一次。
编辑:这个示例基于您正在使用淘汰赛的想法。
JSON:请注意,如果您正在使用淘汰赛,该对象将使用 ko.observable 函数或淘汰赛的使用进行注释。 mapping.js 可用于在整个项目
HTML 中自动应用值:
您可以从其网站上的教程中获取有关淘汰赛实施的其余详细信息。
Have you thought of sending it down to the view as JSON data and binding it to a template in the client side or using a library like knockout.
The size of the data you are sending is increased largely because you are repeating the same html which you are generating for each of the 3k clients. If you send that down with out mark up the size will be much smaller, and then the code for your list item can be sent down only once with place holders for json data.
EDIT: This example is based on the idea that you are using knockout.
JSON: Mind you if you are using knockout, this object would be annotated with ko.observable functions, or the use of the knockout.mapping.js could be used to auto apply the values across the entire onject
HTML:
You can get the rest of the detail on implementation of knockout from the tutorials on their site.