如何在初始viewmodel加载为空时初始化Knockout视图模型

时间:2012-10-19 20:58:05

标签: javascript asp.net-mvc knockout.js knockout-mapping-plugin

我正在使用Knockout来实现课程列表选择工具。我正在使用下面的方法来填充数据(MVC3 / Razor),这样当最初填充viewmodel时,我对使用每个KO数组(即CourseList,ScheduleList)没有任何问题。但是,当来自服务器的初始加载返回零行时,意味着视图模型'ScheduleList'属性为空,则无法调用任何方法,如.push()或.removeAll()。据推测,这意味着从未创建过可观察数组,因为没有任何内容可以填充它。填充模型时,ScheduleList属性将填充List。当MVC操作将其返回为空时,实例化它的最佳方法是什么?有一个似乎解决它的jsFiddle,但是当我尝试使用'create'选项时,它会将我的整个模型呈现为空白。我不确定'create'选项的语法是什么。 jsFiddle在这里:http://jsfiddle.net/rniemeyer/WQGVC/

// Get the data from the server
var DataFromServer = @Html.Raw(Json.Encode(Model));     

// Data property in viewmodel
var data = {
    "CourseList": DataFromServer.CourseList ,
    "ScheduleList": DataFromServer.ScheduleList
    };

$(function() {
    // Populate Data property
    viewModel.Data = ko.mapping.fromJS(data);   

    // ko.applyBindings(viewModel, mappingOptions);             
    ko.applyBindings(viewModel);
});

当初始页面加载未填充ScheduleList时,以下代码将引发错误。如果初始页面加载包含数据,则可以调用.removeAll()和.push()等。

var oneA= 'abc';

// push not working                
this.Data.ScheduleList.push( oneA );

2 个答案:

答案 0 :(得分:9)

设置映射参数以便在创建时进行设置,为其提供一定的结构。然后它会为你做更新。

最有可能发生的是DataFromServer实际上根本不包含ScheduleList属性。因此,在映射时,永远不会生成相应的属性。映射器只会将现有属性映射到observable。

您需要在视图模型的create选项中设置在未设置任何数组时添加空数组。这样,您的视图模型将最终具有相应的可观察数组。

通过确保CourseListScheduleList是一个数组,映射的视图模型会将它们映射为observableArray个对象,以便您的代码按预期工作。

var DataFromServer = {
    'CourseList': [1,2,3]
    //, 'ScheduleList': []
};

var dataMappingOptions = {
    'create': function (options) {
        var data = options.data;
        data.CourseList = data.CourseList || [];
        data.ScheduleList = data.ScheduleList || [];
        return ko.mapping.fromJS(data);
    }
};

viewModel.Data = ko.mapping.fromJS(DataFromServer, dataMappingOptions);

答案 1 :(得分:1)

var data = {
    CourseList: DataFromServer.CourseList || ko.observableArray([]) ,
    ScheduleList: DataFromServer.ScheduleList  || ko.observableArray([])
    };