AJAX编辑的网页。如何提供初始数据?

时间:2013-04-18 15:48:02

标签: javascript asp.net ajax knockout.js

我的网页包含表格数据。现在它使用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加载相比,首次加载速度更快..

1 个答案:

答案 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;
};