如何在KnockOut双重嵌套映射中添加父函数? [英] How to add parent function to KnockOut double-nested mapping?

查看:83
本文介绍了如何在KnockOut双重嵌套映射中添加父函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用fromJS的KnockOut映射从JSON对象创建我的视图模型,如下所示:

{
    "cats": [{
        "name": "fluffy",
        "color": "brown",
        "kittens": [{
            "name": "spot",
            "color": "brown"
        }, {
            "name": "rascal",
            "color": "grey"
        }, {
            "name": "trouble",
            "color": "white"
        }]
    }, {
        "name": "kitty",
        "color": "red",
        "kittens": [{
            "name": "lady",
            "color": "red"
        }, {
            "name": "skat",
            "color": "striped"
        }]
    }]
}

html:

<div data-bind="foreach:cats">
    <span data-bind="text:name"></span>
    <table>
        <tr data-bind="foreach: kittens">
             <td data-bind="text:name"></td>
             <td data-bind="text:color"></td>
             <td><a data-bind="click: $parent:showParentColor" href="#">Parent Color</a></td>
        </tr>
    </table>
</div>

Javascript:

var KittenModel = function (data) {
    ko.mapping.fromJS(data, {}, this);

    // ... various computed values added to this
}

var mapping = {
    'kittens': {
        create: function(options) {
            return new KittenModel(options.data);
        }
    },
    'otherItem': {
        create: function(options) {
             return ('otherStuff');
        }
     }
}

var data = { ... }; // the JSON above

var CatsViewModel = ko.mapping.fromJS(data, mapping);

问题:

我在哪里以及如何放置showParentColor()函数,以便数据绑定在小猫表中起作用?例如:

function showParentColor(cat) {
    alert(cat.color);
}

谢谢!

解决方案

您可以根据您的视图模型层次结构使用以下一种方法:

  • $ root :这指向根上下文中的主视图模型对象.父级上下文最高.
  • $ parents数组:这是一个包含所有视图模型的数组.

    • $ parents [0]:父视图模型上下文.(也与$parent相同)

    • $ parents [1]::第二个父视图模型上下文.(祖父母)

    • $ parents [2]::第三个​​父视图模型上下文. (曾祖父母)

    • 以此类推....


更新: 如果要在CatsViewModel级别添加功能,只需将功能添加到创建的模型中即可.

示例: https://jsfiddle.net/kyr6w2x3/87/

JS:

 CatsViewModel.showParentColor = function(item){
      console.log(item.name());
      console.log(item.color());
    }

查看:

<a data-bind="click: $parents[1].showParentColor">

下面是模型的层次结构

- CatsViewModel 
    - cats : observableArray
        - name : observable
        - color : observable
        - kittens : observableArray
               - name : observable
               - color : observable
    - showParentColor : function


替代方法:您可以自己完成工作并创建模型.可以轻松根据您的需要进行修改和维护.您还可以在所需的任何模型中添加click函数. /p>

示例: http://jsfiddle.net/kyr6w2x3/91/

HTML:

<div data-bind="foreach:cats">
    <span data-bind="text:name"></span>
    <table>
    <tbody data-bind="foreach: kittens">
       <tr>
             <td data-bind="text:name"></td>
             <td data-bind="text:color"></td>
             <td><a data-bind="click: $parent.showParentColor" href="#">Parent Color</a></td>
        </tr>
    </tbody>

    </table>
</div>

JS:

 var data = {
    "cats": [{
        "name": "fluffy",
        "color": "brown",
        "kittens": [{
            "name": "spot",
            "color": "brown"
        }, {
            "name": "rascal",
            "color": "grey"
        }, {
            "name": "trouble",
            "color": "white"
        }]
    }, {
        "name": "kitty",
        "color": "red",
        "kittens": [{
            "name": "lady",
            "color": "red"
        }, {
            "name": "skat",
            "color": "striped"
        }]
    }]
}

var CatsViewModel = function (data){ 
  var self = this;
  self.cats = ko.observableArray($.map(data.cats, function (item) {
        return new CatItemViewModel(item);
    }));
}
var CatItemViewModel = function (data){
  var self = this;
  self.name = ko.observable(data.name);
  self.color = ko.observable(data.color);
  self.kittens = ko.observableArray($.map(data.kittens, function (item)     {
   var newData = Object.assign({}, item, { parent: self.name()});
        return new KittenModel(newData);
   }));
   self.showParentColor = function (item){
      console.log("Parent Name: " , self.name());
      console.log("Name: " , item.name());
      console.log("Color: " , item.color());
   }
}
var KittenModel = function (data) {
  var self = this;
  self.name = ko.observable(data.name);
  self.color = ko.observable(data.color);
  self.parent = ko.observable(data.parent);
}
var vm = new CatsViewModel(data);
ko.applyBindings(vm);

I'm using KnockOut mapping fromJS to create my View Model from a JSON object like the following:

{
    "cats": [{
        "name": "fluffy",
        "color": "brown",
        "kittens": [{
            "name": "spot",
            "color": "brown"
        }, {
            "name": "rascal",
            "color": "grey"
        }, {
            "name": "trouble",
            "color": "white"
        }]
    }, {
        "name": "kitty",
        "color": "red",
        "kittens": [{
            "name": "lady",
            "color": "red"
        }, {
            "name": "skat",
            "color": "striped"
        }]
    }]
}

html:

<div data-bind="foreach:cats">
    <span data-bind="text:name"></span>
    <table>
        <tr data-bind="foreach: kittens">
             <td data-bind="text:name"></td>
             <td data-bind="text:color"></td>
             <td><a data-bind="click: $parent:showParentColor" href="#">Parent Color</a></td>
        </tr>
    </table>
</div>

Javascript:

var KittenModel = function (data) {
    ko.mapping.fromJS(data, {}, this);

    // ... various computed values added to this
}

var mapping = {
    'kittens': {
        create: function(options) {
            return new KittenModel(options.data);
        }
    },
    'otherItem': {
        create: function(options) {
             return ('otherStuff');
        }
     }
}

var data = { ... }; // the JSON above

var CatsViewModel = ko.mapping.fromJS(data, mapping);

Question:

Where and how do I put the showParentColor() function so that the the data-bind works in the kitten table? For example:

function showParentColor(cat) {
    alert(cat.color);
}

Thanks!

解决方案

You may use one of the following based on your view model hierarchy :

  • $root : This points to the main view model object in the root context.The top most parent context.
  • $parents array : This is an array which contains all your view models.

    • $parents[0] : The parent view model context.(also it’s the same as $parent)

    • $parents[1]: The second parent view model context.(grand parent)

    • $parents[2]: The third parent view model context . (great-grand parent)

    • And so on....


Update : If you want to add a function in CatsViewModel level, you simply add your function to created model.

Example :https://jsfiddle.net/kyr6w2x3/87/

JS:

 CatsViewModel.showParentColor = function(item){
      console.log(item.name());
      console.log(item.color());
    }

View:

<a data-bind="click: $parents[1].showParentColor">

Below is the hierarchy of your model

- CatsViewModel 
    - cats : observableArray
        - name : observable
        - color : observable
        - kittens : observableArray
               - name : observable
               - color : observable
    - showParentColor : function


Alternative : You can do the job yourself and create your models.Would be easier for you to modify and maintain based on what you want.You can also add click function inside any models you want.

Example :http://jsfiddle.net/kyr6w2x3/91/

HTML :

<div data-bind="foreach:cats">
    <span data-bind="text:name"></span>
    <table>
    <tbody data-bind="foreach: kittens">
       <tr>
             <td data-bind="text:name"></td>
             <td data-bind="text:color"></td>
             <td><a data-bind="click: $parent.showParentColor" href="#">Parent Color</a></td>
        </tr>
    </tbody>

    </table>
</div>

JS:

 var data = {
    "cats": [{
        "name": "fluffy",
        "color": "brown",
        "kittens": [{
            "name": "spot",
            "color": "brown"
        }, {
            "name": "rascal",
            "color": "grey"
        }, {
            "name": "trouble",
            "color": "white"
        }]
    }, {
        "name": "kitty",
        "color": "red",
        "kittens": [{
            "name": "lady",
            "color": "red"
        }, {
            "name": "skat",
            "color": "striped"
        }]
    }]
}

var CatsViewModel = function (data){ 
  var self = this;
  self.cats = ko.observableArray($.map(data.cats, function (item) {
        return new CatItemViewModel(item);
    }));
}
var CatItemViewModel = function (data){
  var self = this;
  self.name = ko.observable(data.name);
  self.color = ko.observable(data.color);
  self.kittens = ko.observableArray($.map(data.kittens, function (item)     {
   var newData = Object.assign({}, item, { parent: self.name()});
        return new KittenModel(newData);
   }));
   self.showParentColor = function (item){
      console.log("Parent Name: " , self.name());
      console.log("Name: " , item.name());
      console.log("Color: " , item.color());
   }
}
var KittenModel = function (data) {
  var self = this;
  self.name = ko.observable(data.name);
  self.color = ko.observable(data.color);
  self.parent = ko.observable(data.parent);
}
var vm = new CatsViewModel(data);
ko.applyBindings(vm);

这篇关于如何在KnockOut双重嵌套映射中添加父函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆