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

时间:2021-05-23 20:37:32

I am using Knockout to implement a course list selection tool. 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 (i.e. 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(). 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. What is the best way to instantiate it when the MVC action returns it as empty? There is a jsFiddle that seems to address it, but when I try to use the 'create' option, it renders my entire model blank. I am not sure what the syntax is of the 'create' option. The jsFiddle is here: http://jsfiddle.net/rniemeyer/WQGVC/

我正在使用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);
});

When the initial page load does not populate ScheduleList, then the following code throws an error. If the initial page load contained data, then you could call .removeAll() and .push() etc.

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

var oneA= 'abc';

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

2 个解决方案

#1


9  

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. So when it is mapped, a corresponding property is never made. The mapper will only map existing properties to observables.

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

You need to set in your create options for the view model to add empty arrays when either array is not set. 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.

通过确保CourseList或ScheduleList是一个数组,映射的视图模型将它们映射为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);

#2


1  

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

#1


9  

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. So when it is mapped, a corresponding property is never made. The mapper will only map existing properties to observables.

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

You need to set in your create options for the view model to add empty arrays when either array is not set. 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.

通过确保CourseList或ScheduleList是一个数组,映射的视图模型将它们映射为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);

#2


1  

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