我有以下html代码段
<table class="table table-striped" style="background-color:white!important" data-bind="visible:!loading(),fixedHeader:loading">
<thead >
<tr>
<th data-bind="click:sortSurname">Surname
<!-- ko if:whatToSort() == 'surname'-->
<i class="fa fa-caret-up" data-bind="visible:ascending"></i>
<i class="fa fa-caret-down" data-bind="visible:!ascending()"></i>
<!-- /ko -->
<!-- ko ifnot:whatToSort() == 'surname'-->
<i class="fa fa-sort fa-pos-conf" ></i>
<!-- /ko -->
</th>
<th data-bind="click:sortName">Name
<!-- ko if:whatToSort() == 'name'-->
<i class="fa fa-caret-up" data-bind="visible:ascending"></i>
<i class="fa fa-caret-down" data-bind="visible:!ascending()"></i>
<!-- /ko -->
<!-- ko ifnot:whatToSort() == 'name'-->
<i class="fa fa-sort fa-pos-conf" ></i>
<!-- /ko -->
</th>
<th data-bind="click:sortTitle">Business Title
<!-- ko if:whatToSort() == 'title'-->
<i class="fa fa-caret-up" data-bind="visible:ascending"></i>
<i class="fa fa-caret-down" data-bind="visible:!ascending()"></i>
<!-- /ko -->
<!-- ko ifnot:whatToSort() == 'title'-->
<i class="fa fa-sort fa-pos-conf" ></i>
<!-- /ko -->
</th>
<th data-bind="click:sortOrganization">Organization
<!-- ko if:whatToSort() == 'organization'-->
<i class="fa fa-caret-up" data-bind="visible:ascending"></i>
<i class="fa fa-caret-down" data-bind="visible:!ascending()"></i>
<!-- /ko -->
<!-- ko ifnot:whatToSort() == 'organization'-->
<i class="fa fa-sort fa-pos-conf" ></i>
<!-- /ko -->
</th>
</tr>
</thead>
<tbody data-bind="foreach:sorteddata">
<tr>
<td><span data-bind="text:surname"></span></td>
<td><span data-bind="text:name"></span></td>
<td><span data-bind="text:title"></span></td>
<td><span data-bind="text:organization"></span></td>
</tr>
</tbody>
</table>
以下视图模型:
function CompanyViewModel()
{
var list=this;
list.data=ko.observableArray([
new BusinessMen({id:1,name:"john",surname:"doe",title:"Harem Maker",organization:"Harem Ltd"}),
new BusinessMen({id:2,name:"Alan",surname:"doe",title:"CEO",organization:"Harem Ltd"}),
new BusinessMen({id:1,name:"miss",surname:"piggy",title:"Piug Manager",organization:"Pig Ltd"}),
....
new BusinessMen({id:1,name:"Bill",surname:"Gates",title:"MIcrosoft's Former CEO",organization:"Microsoft Inc"}),
]);
list.whatToSort=ko.observable('surname'); //Tell with what to sort the table
list.ascending=ko.observable(false); //Tell the order to sort
/**
*Callback for sorting
*/
var sortFunc=function(a,b)
{
switch(list.whatToSort())
{
case 'name':
a=a.name;
b=b.name;
break;
case 'title':
a=a.title;
b=b.title;
break;
case 'organization':
a=a.organization;
b=b.organization;
break;
case 'surname':
default:
a=a.surname;
b=b.surname;
}
if(!list.ascending())//Swap if desceding
{
var temp=b;
b=a;
a=temp;
}
if(typeof a ==='undefined' || typeof b === 'undefined') return 0;
return ( ( a() == b() ) ? 0 : ( ( a() > b() ) ? 1 : -1 ) );
};
list.sortSurname=function()
{
list.whatToSort('surname');
list.ascending(!list.ascending());
};
list.sortName=function()
{
list.whatToSort('name');
list.ascending(!list.ascending());
}
list.sortOrganization=function()
{
list.whatToSort('organization');
list.ascending(!list.ascending());
}
list.sortTitle=function()
{
list.whatToSort('title');
list.ascending(!list.ascending());
}
/**
*Sorted Data depending what we select
*/
list.sorteddata=ko.pureComputed(function()
{
return list.data().sort(sortFunc);
});
function BusinessMen(data)
{
var buinessman=this;
data.id=parseInt(data.id);
data.name=ko.observable(data.name);
data.surname=ko.observable(data.surname);
data.title=ko.observable(data.title);
data.organization=ko.observable(data.organization);
}
}
最后绑定Handler:
ko.bindingHandlers.fixedHeader={
update:function(element, valueAccessor, allBindings, viewModel, bindingContext)
{
$(element).freezeHeader({offset : '50px'});
}
};
上面的代码使用freezeheader.js(https://laertejjunior.github.io/freezeheader/)和knockout.js在表格顶部显示一个固定的标题。
问题是,当我向下滚动并显示“冻结”标题时,我无法对数据进行排序,特别是当我点击标题选择排序键然后没有项目执行时我不知道为什么这样做发生。
也许请一些帮助;
答案 0 :(得分:1)
Freezeheader库使用数据绑定DOM元素的克隆来显示视口顶部的粘性标题。它将此克隆附加到DOM的方式是:
tabela.append('<thead>' + obj.header.html() + '</thead>');
克隆的HTML元素可能看起来与其原始元素类似,但它会丢失与事件侦听器的所有连接,或者在您的情况下,丢失与淘汰数据绑定上下文的连接。
jQuery的clone
方法有一个选项,不仅可以复制原始HTML,还可以复制附加到它的任何事件监听器。通过传递true
参数来使用它:element.clone(true)
为您提供带有复制的事件侦听器的副本。 (source)
您不是第一个遇到此问题的Freezeheader用户。 Github用户Shafranov发布a pull request,用jQuery的clone(true)
方法替换下面显示的代码行。
在进行此更改之前,请确保您没有违反任何其他数据绑定。虽然jQuery可能会为您复制click侦听器,但它可能无法使knockout从一个视图模型中更新DOM中两个位置的文本或值。