【问题标题】:Using KnockoutJS automatic binding使用 KnockoutJS 自动绑定
【发布时间】:2013-06-24 19:23:30
【问题描述】:

我正在尝试将 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 的新手,所以我想我正在做一些非常愚蠢的事情,如果是,请指出我正确的方向。

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

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

    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,它会在回调中为您提供数据:

    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 将它们导入视图模型文件,然后在整个应用程序中使用它们。这将允许属性名称更改和更新在前端自动可用,只需在后端更新模型。

    【讨论】:

    • 感谢@XGreen 的解释。我使用以下内容成功绑定到 html var organizationData = data.d; var orgObject = { 组织数据:组织数据 }; var newviewmodel = ko.viewmodel.fromModel(orgObject);你能告诉我如何附加一个监听器,以便当我的底层数组对象发生变化时我可以调用一个 ajax 函数吗?
    • 答案是否为您提供了解决方案?
    • 我想要一种不需要太多 JS 编码的简单方法。谢谢,我明白我可以很好地实现 KO。我有一个后续问题stackoverflow.com/questions/17422552/…。你能帮我回答一下吗
    • 您的新问题的答案也在这里。您可以在有关 datacontext.getActivities 的部分中看到,我在 ajax 的回调中调用了敲除的 applyBindings 方法,以确保在请求敲除应用绑定之前数据存在
    猜你喜欢
    • 1970-01-01
    • 2012-01-22
    • 2015-01-29
    • 2013-02-08
    • 2013-02-22
    • 2023-04-02
    • 1970-01-01
    • 2016-02-14
    • 2012-10-15
    相关资源
    最近更新 更多