简体   繁体   English

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

[英]How to initialize a Knockout viewmodel when initial viewmodel load is empty

I am using Knockout to implement a course list selection tool. 我正在使用Knockout来实现课程列表选择工具。 I am using the approach below to populate the data (MVC3/Razor), so that when the viewmodel is initially populated, I have no issues working with each KO array (ie CourseList, ScheduleList). 我使用下面的方法来填充数据(MVC3 / Razor),这样当最初填充viewmodel时,我对每个KO数组(即CourseList,ScheduleList)没有任何问题。 However, when the initial load from the server returns zero rows, meaning that the viewmodel 'ScheduleList' property is empty, then it's not possible to call any methods such as .push() or .removeAll(). 但是,当来自服务器的初始加载返回零行时,意味着视图模型'ScheduleList'属性为空,则无法调用任何方法,如.push()或.removeAll()。 Presumably this means that the observable array was never created since there was nothing to fill it with. 据推测,这意味着从未创建过可观察数组,因为没有任何内容可以填充它。 When the model is filled, the ScheduleList property is populated with a List. 填充模型时,ScheduleList属性将填充List。 What is the best way to instantiate it when the MVC action returns it as empty? 当MVC操作将其返回为空时,实例化它的最佳方法是什么? There is a jsFiddle that seems to address it, but when I try to use the 'create' option, it renders my entire model blank. 有一个似乎解决它的jsFiddle,但是当我尝试使用'create'选项时,它会将我的整个模型呈现为空白。 I am not sure what the syntax is of the 'create' option. 我不确定'create'选项的语法是什么。 The jsFiddle is here: http://jsfiddle.net/rniemeyer/WQGVC/ 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);
});

When the initial page load does not populate ScheduleList, then the following code throws an error. 当初始页面加载未填充ScheduleList时,以下代码将引发错误。 If the initial page load contained data, then you could call .removeAll() and .push() etc. 如果初始页面加载包含数据,那么您可以调用.removeAll()和.push()等。

var oneA= 'abc';

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

Set up your mapping parameters to make it so on creation, you give it a certain structure. 设置映射参数以便在创建时创建它,为它提供一定的结构。 Then it will do the updates for you. 然后它会为你做更新。

What is most likely happening is that your DataFromServer doesn't actually contain a ScheduleList property at all. 最可能发生的是您的DataFromServer实际上根本不包含ScheduleList属性。 So when it is mapped, a corresponding property is never made. 因此,在映射时,永远不会生成相应的属性。 The mapper will only map existing properties to observables. 映射器仅将现有属性映射到observable。

You need to set in your create options for the view model to add empty arrays when either array is not set. 您需要在视图模型的create选项中设置,以便在未设置任何数组时添加空数组。 That way, your view model will end up with corresponding observable arrays in place. 这样,您的视图模型将最终具有相应的可观察数组。

By ensuring that CourseList or ScheduleList is an array, the mapped view model will map them as observableArray objects so your code will work as you expected. 通过确保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);
var data = {
    CourseList: DataFromServer.CourseList || ko.observableArray([]) ,
    ScheduleList: DataFromServer.ScheduleList  || ko.observableArray([])
    };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM