敲定绑定与每个定制 [英] Knockout binding with a customization in for each

查看:77
本文介绍了敲定绑定与每个定制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是我的代码:





pre> < div id =content-wrapper>

< div id =akjsdbgb>
< table>
< tbody data-bind =foreach:resultData>
< tr>
< td data-bind =text:fieldName>< / td>
< td data-bind =text:fieldValue>< / td>
< / tr>
< / tbody>
< / table>
< / div>

< / div>



型号:



  self.resultData = ko.observableArray([]); 

self.getResultData = function(){
var data = Cobalt.Data.getResultData();
self.resultData(data.searchDataList);
};
};

Models.Field = function(data){

var self = this;
self.fieldName = data.fieldName;
self.fieldValue = data.fieldValue;

};

问题是我需要从fieldData和fieldValue格式的resultData中创建表格数据,该表应该在tr中有两组数据,意味着在b中的数据数组中包含单个fieldName和fieldValue;所以我们需要在tr中循环两次数据,然后递增它。



输出为期望:



< hr>

| FieldName1 | FieldValue2 || FieldName3 | FieldValue4 |



| FieldName5 | FieldValue6 || FieldName7 | FieldValue8 |


解决方案

您可以创建一个计算器来对物品进行配对,如下所示:
$ b

  self.rows = ko.computed(function(){
var allItems = self.resultData();
var rows = [];
for(var i = 0,len = allItems.length; i< len; i = i + 2){
rows.push({
leftItem:allItems [i ],
rightItem:i + 1< len?allItems [i + 1]:null
});
}
返回行;
});

然后,您将绑定到属性而不是直接绑定到 resultData 属性。



编辑:@GOK在评论中询问了一个版本这将允许在一行中定制数量的项目。



您可以通过执行以下操作轻松实现此目的:

  self.itemsOnEachRow = ko.observable(2); 
self.rows = ko.computed(function(){
var allItems = self.resultData();
var itemsPerRow = self.itemsOnEachRow();
var rows = [ ];
for(var i = 0,len = allItems.length; i< len; i = i + itemsPerRow){
var row = {};
for(var itemIndex = 0; itemIndex< itemsPerRow; itemIndex ++){
var item = null;
if(i + itemIndex< len){
item = allItems [i + itemIndex];
}
row ['item'+ itemIndex] = item;
}
rows.push(row);
}
return rows;
}) ;

然后每一行都会有一个名为 item1 item2 等与由 itemsOnEachRow observable设置的项目数量关联(其中一些属性可能包含null如果总项目计数不能被每行计数的项目平均整除)。

我已经写了一个样本,你可以在上找到http://jsfiddle.net/af7P2/ ,但我不建议按照在该示例中完成的方式来绑定表。我不确定它将如何设置订阅,但它可能多次订阅计算,每行一次。它只是显示行的样本的计算结果,而不是其他任何内容。



如果你想要每行作为一个数组本身,你可以使用下面的代码:

  self.itemsOnEachRow = ko.observable(2) ; 
self.rows = ko.computed(function(){
var allItems = self.resultData();
var itemsPerRow = self.itemsOnEachRow();
var rows = [ ];
for(var i = 0,len = allItems.length; i< len; i = i + itemsPerRow){
var row = [];
for(var itemIndex = 0; itemIndex< itemsPerRow; itemIndex ++){
var item = null;
if(i + itemIndex< len){
item = allItems [i + itemIndex];
}
row.push(item);
}
rows.push(row);
}
return rows;
});

此版本的绑定(您可以在 http://jsfiddle.net/af7P2/1/ )稍微好一点,因为它不使用为每一行计算一次。



一般来说,这个解决方案可能表现不佳,视您的情况而定。任何对 resultData 数组添加/删除项目或对 itemsOnEachRow 值的更改都会重新绑定整个表格。可能不是你的问题,只是需要注意的事情。


I have a situation here for the knockout with for each binding with customization

Here is my code:

<div id="content-wrapper">

    <div id="akjsdbgb">
        <table>
            <tbody data-bind="foreach: resultData">
                <tr>
                    <td data-bind="text: fieldName"></td>
                    <td data-bind="text: fieldValue"></td>
                </tr>               
            </tbody>
        </table>
    </div>

</div>

Model:

    self.resultData = ko.observableArray([]);

    self.getResultData = function () {
        var data = Cobalt.Data.getResultData();
        self.resultData(data.searchDataList);
    };
};

Models.Field = function(data) {

    var self = this;
    self.fieldName = data.fieldName;
    self.fieldValue = data.fieldValue;

};

The problem is i need to create a tabular data from the resultData which is in fieldName and fieldValue formats and the table should be having two sets of data in a single tr means

4 's in a tr but the data array contains single fieldName and fieldValue; so we need to loop in a tr for two times of data and then increment it.

OUTPUT AS EXPECTED:


| FieldName1 |FieldValue2 || FieldName3 |FieldValue4 |

| FieldName5 | FieldValue6 || FieldName7 |FieldValue8 |

解决方案

You could create a computed which would pair items, something like the following:

self.rows = ko.computed(function(){
    var allItems = self.resultData();
    var rows = [];
    for(var i = 0, len = allItems.length; i < len; i = i+2){
        rows.push({
            leftItem: allItems[i],
            rightItem: i + 1 < len ? allItems[i + 1] : null
        });
    }
    return rows;
});

You would then bind to the rows property instead of binding directly to the resultData property.

EDIT: @GOK asked, in a comment, for a version which would allow customizable number of items in a single row.

You could achieve this easily by doing something like the following:

self.itemsOnEachRow = ko.observable(2);
self.rows = ko.computed(function(){
    var allItems = self.resultData();
    var itemsPerRow = self.itemsOnEachRow();
    var rows = [];
    for(var i = 0, len = allItems.length; i < len; i = i + itemsPerRow){
        var row = {};
        for(var itemIndex = 0; itemIndex < itemsPerRow; itemIndex++){
            var item = null;
            if (i + itemIndex < len){
                item = allItems[i + itemIndex];
            }
            row['item' + itemIndex] = item;
        }
        rows.push(row);
    }
    return rows;
});

Each row would then have properties named item1, item2, etc, to the number of items set by the itemsOnEachRow observable (some of these properties might hold a null reference, if the total item count isn't evenly divisible by the items per row count).

I have written a sample on this, which you can find on http://jsfiddle.net/af7P2/, but I do not suggest binding the table in the way it is done in that sample. I'm not sure how it would set up subscriptions, but it might subscribe a multitude of times to the columns computed, one time for each row. It's just there to show a sample of the rows computed, not for anything else.

If you want each row to be an array in itself, you could do it with the following code:

self.itemsOnEachRow = ko.observable(2);
self.rows = ko.computed(function(){
    var allItems = self.resultData();
    var itemsPerRow = self.itemsOnEachRow();
    var rows = [];
    for(var i = 0, len = allItems.length; i < len; i = i + itemsPerRow){
        var row = [];
        for(var itemIndex = 0; itemIndex < itemsPerRow; itemIndex++){
            var item = null;
            if (i + itemIndex < len){
                item = allItems[i + itemIndex];
            }
            row.push(item);
        }
        rows.push(row);
    }
    return rows;
});

The bindings for this version (which you can find at http://jsfiddle.net/af7P2/1/) is a bit better, since it doesn't use the columns computed one time for each row.

In general, this solution might not perform very well, depending on your situation. Any addition/removal of items to the resultData array, or a change to the itemsOnEachRow value, would rebind the whole table. Might not be a problem for you, just something to be aware of.

这篇关于敲定绑定与每个定制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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