我有一个包含表格数据的网页。现在它使用 Knockout.js 绑定(bind)。
当页面加载时,我进行 AJAX 调用以获取数据并进行绑定(bind)。基本上,页面首先显示,然后用户收到“正在加载...”ajax 消息和数据。这很好,因为页面加载速度很快,但浏览器必须对服务器进行 2 次调用(一次用于页面,另一次用于数据)。
如果用户想要刷新数据 - 它也可以以同样的方式很好地工作。
我想知道如何将 ViewModel 数据与页面一起加载?有什么办法可以避免两次访问服务器?我想以某种方式在初始页面加载时包含 JSON,然后使用它并使用 AJAX 刷新它。
编辑:
我让它工作了,不确定我这样做的方式是否有任何陷阱:
HTML:
<div id="initialData" style="display: none;"><asp:Literal ID="initialDataLiteral" runat="server" EnableViewState="False"/></div>
服务器代码:
// Prepare initial data for page
var memoryStream = new MemoryStream();
var serializer = new DataContractJsonSerializer(typeof(DataEnvelope));
serializer.WriteObject(memoryStream, GetShipments(DateTime.Now.Date.AddMonths(-2).ToShortDateString(), DateTime.Now.Date.ToShortDateString()));
memoryStream.Position = 0;
var streamreader = new StreamReader(memoryStream);
this.initialDataLiteral.Text = streamreader.ReadToEnd();
在 Knockout 方面很简单,我只需取出字符串,转换为 JSON 并使用它......
// Page comes with preloaded data. Let's set VM properties
var initialData = $.parseJSON($("#initialData").text());
vm.tripData(ko.utils.arrayMap(initialData.Shipments, function (i) { return new shipment(i); }));
稍后当用户点击刷新时,他们通过 AJAX 调用获得相同的数据。这样做有什么缺点吗?显然查看源代码给出了一堆 JSON“东西”。我仍然认为与完全 ajax 加载相比,页面更紧凑,首次加载速度更快。
最佳答案
您没有具体说明您使用的是什么服务器端技术,但您至少用 asp.net
标记了问题。这是我在 ASP.NET MVC 中使用的模式,因此如果您使用的是 Web 窗体,则可能需要对其进行调整。
var modelData = @Html.Raw(Json.Encode(Model));
var MyViewModel = function (data) {
var model = ko.mapping.fromJS(data);
// any additional observables, computeds, methods, etc., i.e.
// model.SomethingNotOnModel = ko.computed();
return model;
};
var viewModel = MyViewModel(modelData);
ko.applyBindings(viewModel);
Knockout 的映射插件将自动为提供给它的数据对象上存在的任何属性创建可观察对象,因此您无需手动指定这些属性,除非您需要更改它们。
更新
根据@Rich 的评论,我觉得我应该更清楚地展示你应该如何实际使用它:
页面内
<script>
$(document).ready(function () {
var modelData = @Html.Raw(Json.Encode(Model));
MyApp.MyView.Init(modelData);
});
</script>
外部 JS
MyApp = MyApp || {};
MyApp.MyView = function () {
var _init = function (data) {
var viewModel = MyApp.MyView.MyViewModel(data);
ko.applyBindings(viewModel);
// anything else that should happen on page load
};
return {
Init: _init
};
}();
MyApp.MyView.MyViewModel = function (data) {
var model = ko.mapping.fromJS(data);
// any additional observables, computeds, methods, etc., i.e.
// model.SomethingNotOnModel = ko.computed();
return model;
};
关于javascript - AJAX 版网页。我如何携带初始数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16087513/