我的网页包含表格数据。现在它使用Knockout.js绑定。
当页面加载时,我进行AJAX调用以带来数据和绑定。基本上,首先显示页面,而不是用户获取“正在加载...”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调用获得相同的数据。像这样有任何缺点吗?显然,View源代码提供了一堆JSON“东西”。我仍然认为页面更紧凑,并且与完全ajaxed加载相比,首次加载速度更快..
答案 0 :(得分:1)
您没有指定您正在使用的服务器端技术,但您至少使用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的映射插件会自动为输入的数据对象上的任何属性创建observable,因此除非需要更改,否则不需要手动指定它们。
<强>更新强>
基于@ 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;
};