0

我正在尝试将 List=>List=>List=>List 对象绑定到 Knockout JS 视图模型中。

我来自 $getJSON 的数据如下主要对象类型描述

我尝试使用映射插件创建一个视图模型,例如:- var viewModel = ko.mapping.fromJS(d.organisationsData);

问题是我不知道为什么(/是否)映射正确发生。

我无法使用数据绑定来迭代此 List 和 innerList 属性

这是我的 ViewModel 对象

查看模型对象

我尝试使用 data-bind: for-each ListOfOrg 进行迭代,它显示绑定错误 ListOfOrg is not found。

<ul data-bind="foreach:ListOfOrg">

我是 KnockoutJS 的新手,所以我想我正在做一些非常愚蠢的事情,如果是,请指出我正确的方向。

4

1 回答 1

2

好的,让我们看一个简单的例子,假设我们想在页面上显示一些活动。

  1. 假设您返回的数据是所有具有某些属性的活动的枚举,那么您的活动可能看起来像这样:
var ActivityType = function (data) {
       var self = this;
       self.Id = ko.observable(data.Id);
       self.Name = ko.observable(data.Name);
       self.Description = ko.observable(data.Description);
       self.Selected = ko.observable(data.Selected); };

然后你有一个视图模型,它有一个名为活动的属性,它需要映射到这个活动模型,所以当你得到你的活动枚举时,它会自动在该数组中为你生成相同数量的 New ActivityTypes。

var activitiesViewModel = {};

所以我们为此定义了一个映射实用程序(简单地说新的 ActivityTypes 是具有不同 Id 的那些,然后创建一个新的):

var ActivityTypeDataMappingOptions = {
        key: function (data) {
            return data.Id;
        }, create: function (options) {
            return new ActivityType(options.data, null);
        }
    }

所以现在我们需要视图模型上的活动属性:

activitiesViewModel.Activities = mapping.fromJS([]);

这意味着根据映射数据制作一个可观察的数组。

假设您定义了一个数据上下文,该数据上下文为您提供数据,然后在其回调中:

datacontext.getActivities(function (data) {
    mapping.fromJS(data.Activities, ActivityTypeDataMappingOptions, activitiesViewModel.Activities);
    ko.applyBindings(activitiesViewModel);
});

mapping.fromJS 需要 3 个参数,第一个是要包含数据的集合,第二个是我们定义的映射实用程序,因此可以从包含可观察集合的视图模型上的属性中创建新的活动,最后是属性。

所以现在你可以像这样使用它:

<ul data-bind="foreach: Activities">
     <li><input type='text' data-bind="value: Name" /></li>
</ul>
<button data-bind="click: updateActivities">Update Activities</button>
  • 注意:在这个示例中,视图模型是一个单例,但您可能希望根据您的使用情况,使用显示原型模式使其成为可实例化的对象。然后,当您调用 ko.applyBindings 时,您需要将 new activitiesViewModel() 作为参数传递。

现在为了更新和发回我们需要定义 updateActivities 的结果:

activitiesViewModel.updateActivities = function(){
     // Let's say our data context also has a setActivities method that requires a payload of activities object for Post
    datacontext.setActivities({
        // as activitiesViewModel.Activities is an observable array then this will always have the latest values which might have changed in your UI
        activities : ko.toJSON(activitiesViewModel.Activities)
    }, function(data){
     // Lets say the POST will return true if the call was successful
        if (data) alert("all done");
    });
};
  • 你也可以绑定这个函数来改变输入,但这会是太多的 API 调用,所以我不推荐它。

  • 如果您正在制作大量这些模型,然后由视图模型使用,您将很快意识到您正在做很多已经在服务器端完成的建模。如果您编写一些服务器端代码自动生成包含模型的 js 文件,例如在我的示例中的 ActivityType,您可以简单地使用 requireJS 将它们导入视图模型文件,然后在整个应用程序中使用它们。这将允许属性名称更改和更新在前端自动可用,只需在后端更新模型。

于 2013-06-27T10:50:07.793 回答