Knockout.js knockout js-使用列标题进行表排序

Knockout.js knockout js-使用列标题进行表排序,knockout.js,html-table,Knockout.js,Html Table,我不熟悉knockout js&需要帮助了解如何使用列标题对表进行动态排序 以下是我的代码的一部分: HTML: <table> <thead> <tr data-bind="click: sortFunction"> <th id='id'>Id</th> <th id='name'>Name</th> <th

我不熟悉knockout js&需要帮助了解如何使用列标题对表进行动态排序

以下是我的代码的一部分:

HTML:

<table>
    <thead>
        <tr data-bind="click: sortFunction">
            <th id='id'>Id</th>
            <th id='name'>Name</th>
            <th id='description'>Description</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: deptList">
        <tr>
            <td><span data-bind="text: id" /></td>
            <td><span data-bind="text: name" /></td>
            <td><span data-bind="text: description" /></td>
        </tr>    
    </tbody>
</table>
self.deptList = ko.observableArray(mylist);
self.sortColumn = ko.observable("id");
self.isSortAsc = ko.observable("True");

var Dept = function(id, name, description) {
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.description = ko.observable(description);
};

var mylist = [
    new Dept(1, "Dept 1", "D1"),
    new Dept(2, "Dept 2", "D6"),
    new Dept(3, "Dept 3", "D3"),
    new Dept(4, "Dept 4", "D4")
];

self.sortFunction = function(data, event) {

    if (self.sortColum === event.target.id)
        self.isSortAsc = !self.isSortAsc;
    else {
        self.sortColumn = event.target.id;
        self.isSortAsc = "True";
    }

    self.deptList.sort(function(a, b) {
        if (self.sortColum === 'id') {
            if (self.isSortAsc)
                a.id < b.id ? -1 : 1;
            else
                a.name < b.name ? 1 : -1;
        } else if (self.sortColum === 'name') {
            if (self.isSortAsc)
                a.name < b.name ? -1 : 1;
            else
                a.name < b.name ? 1 : -1;
        } else(self.sortColum === 'description') {
            if (self.isSortAsc)
                a.description < b.description ? -1 : 1;
            else
                a.description < b.description ? 1 : -1;
        }

    });
};

身份证件
名称
描述
在我的视图模型中,我使用以下函数使用表头对数据表进行排序

视图模型:

<table>
    <thead>
        <tr data-bind="click: sortFunction">
            <th id='id'>Id</th>
            <th id='name'>Name</th>
            <th id='description'>Description</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: deptList">
        <tr>
            <td><span data-bind="text: id" /></td>
            <td><span data-bind="text: name" /></td>
            <td><span data-bind="text: description" /></td>
        </tr>    
    </tbody>
</table>
self.deptList = ko.observableArray(mylist);
self.sortColumn = ko.observable("id");
self.isSortAsc = ko.observable("True");

var Dept = function(id, name, description) {
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.description = ko.observable(description);
};

var mylist = [
    new Dept(1, "Dept 1", "D1"),
    new Dept(2, "Dept 2", "D6"),
    new Dept(3, "Dept 3", "D3"),
    new Dept(4, "Dept 4", "D4")
];

self.sortFunction = function(data, event) {

    if (self.sortColum === event.target.id)
        self.isSortAsc = !self.isSortAsc;
    else {
        self.sortColumn = event.target.id;
        self.isSortAsc = "True";
    }

    self.deptList.sort(function(a, b) {
        if (self.sortColum === 'id') {
            if (self.isSortAsc)
                a.id < b.id ? -1 : 1;
            else
                a.name < b.name ? 1 : -1;
        } else if (self.sortColum === 'name') {
            if (self.isSortAsc)
                a.name < b.name ? -1 : 1;
            else
                a.name < b.name ? 1 : -1;
        } else(self.sortColum === 'description') {
            if (self.isSortAsc)
                a.description < b.description ? -1 : 1;
            else
                a.description < b.description ? 1 : -1;
        }

    });
};
self.deptList=ko.observatarray(mylist);
self.sortColumn=ko.可观察(“id”);
self.isSortAsc=ko.可观察(“真实”);
var Dept=功能(id、名称、描述){
this.id=ko.可观察(id);
this.name=ko.observable(name);
this.description=ko.可观察(description);
};
var mylist=[
新部门(1,“部门1”、“D1”),
新部门(2,“部门2”,“D6”),
新部门(3,“部门3”、“D3”),
新部门(4,“第4部门”、“第4部门”)
];
self.sortFunction=函数(数据、事件){
if(self.sortColum==event.target.id)
self.isSortAsc=!self.isSortAsc;
否则{
self.sortColumn=event.target.id;
self.isSortAsc=“True”;
}
self.deptList.sort(函数(a,b){
if(self.sortColum=='id'){
if(self.isSortAsc)
a、 id
尽管上面的代码正在运行,但我认为应该有更好的方法来实现这一点(我的意思是将列id作为参数传递),这在有大量列时非常有用

我试过左[self.sortColumn]
left[self.sortColumn]
,未按预期工作

如果可以通过动态列名进行排序,请显示示例代码

提前谢谢

left[self.sortColumn] < right[self.sortColumn] ? -1 : 1
而不是

if(self.sortColum === event.target.id)
                    self.isSortAsc = !self.isSortAsc;
                else
                {
                    self.sortColumn = event.target.id;
                    self.isSortAsc = "True";
                } 
我总结了一个有效的例子

<table class="dept_table">
  <thead>
      <tr data-bind="click: sortFunction">
          <th id='id'>Id</th>
          <th id='name'>Name</th>
          <th id='description'>Description</th>
      </tr>
  </thead>

  <tbody data-bind="foreach: deptList">
      <tr>
              <td><span data-bind="text: id" /></td>
              <td><span data-bind="text: name" /></td>
              <td><span data-bind="text: description" /></td>
      </tr>    
  </tbody>
</table>
<script>
// deptlist data
var mylist = [
            {id:1, name:"Dept 1", description: "D1"},
            {id:2, name:"Dept 2", description: "D6"},
            {id:3, name:"Dept 3", description: "D3"},
            {id:4, name:"Dept 4", description: "D4"}];

// Deptlist-item Viewmodel
var Dept = function (data) {
  var self = this;

  for(var key in data){
    // this is the lazy approach usually you should only use observables where they are needed
    if(data.hasOwnProperty(key))this[key] = ko.observable(data[key]);
  }
};

// Deptlist Viewmodel
var Deptlist = function(table_data){
  var self = this;

  this.deptList = ko.observableArray([]);
  this.sortColumn = ko.observable("id");
  this.isSortAsc = ko.observable(true);

  for(var i = 0;i < table_data.length;i++){
    if(table_data.hasOwnProperty(i))this.deptList.push(new Dept(table_data[i]));
  }

  this.sortFunction = function(){
    if(self.sortColumn() === event.target.id)
        self.isSortAsc(!self.isSortAsc());
    else
    {
        self.sortColumn(event.target.id);
        self.isSortAsc(true);
    }

    self.deptList.sort(function (a, b) {
            if(a[self.sortColumn()]() < b[self.sortColumn()]())return !self.isSortAsc();
            else return self.isSortAsc();
    });
  }
};

var deptList = new Deptlist(mylist);

ko.applyBindings(deptList,$('.dept_table')[0]);

</script>

身份证件
名称
描述
//部门列表数据
var mylist=[
{id:1,名称:“部门1”,描述:“D1”},
{id:2,名称:“部门2”,描述:“D6”},
{id:3,名称:“部门3”,描述:“D3”},
{id:4,名称:“部门4”,说明:“D4”}];
//Deptlist项目视图模型
var Dept=功能(数据){
var self=这个;
for(var输入数据){
//这是一种懒惰的方法,通常您应该只在需要观察的地方使用它们
如果(data.hasOwnProperty(key))此[key]=ko.可观察(data[key]);
}
};
//部门列表视图模型
var Deptlist=函数(表数据){
var self=这个;
this.deptList=ko.observearray([]);
this.sortColumn=ko.可观察(“id”);
this.isSortAsc=ko.可观察(真);
对于(变量i=0;i
这是一个快速绑定处理程序,您可以将其添加到th中。单击th后,它将根据绑定中定义的属性名称对列进行排序

ko.bindingHandlers.sort = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var asc = false;
        element.style.cursor = 'pointer';

        element.onclick = function(){
            var value = valueAccessor();
            var prop = value.prop;
            var data = value.arr;

            asc = !asc;

            data.sort(function(left, right){
                var rec1 = left;
                var rec2 = right;

                if(!asc) {
                    rec1 = right;
                    rec2 = left;
                }

                var props = prop.split('.');
                for(var i in props){
                    var propName = props[i];
                    var parenIndex = propName.indexOf('()');
                    if(parenIndex > 0){
                        propName = propName.substring(0, parenIndex);
                        rec1 = rec1[propName]();
                        rec2 = rec2[propName]();
                    } else {
                        rec1 = rec1[propName];
                        rec2 = rec2[propName];
                    }
                }

                return rec1 == rec2 ? 0 : rec1 < rec2 ? -1 : 1;
            });
        };
    }
    };
ko.bindingHandlers.sort={
init:function(元素、valueAccessor、allBindingsAccessor、viewModel、bindingContext){
var-asc=false;
element.style.cursor='pointer';
element.onclick=function(){
var value=valueAccessor();
var prop=value.prop;
var数据=value.arr;
asc=!asc;
数据排序(函数(左、右){
var rec1=左;
var rec2=右;
如果(!asc){
rec1=右;
rec2=左;
}
var props=prop.split('.');
for(道具中的变量i){
var propName=props[i];
var parenIndex=propName.indexOf(“()”);
如果(parenIndex>0){
propName=propName.substring(0,parenIndex);
rec1=rec1[propName]();
rec2=rec2[propName]();
}否则{
rec1=rec1[propName];
rec2=rec2[propName];
}
}
返回rec1==rec2?0:rec1

这有点优雅,因为您不必为每个列创建单独的函数。在这里可以找到一个更完整的工作示例:

感谢@brendonparker为您提供了出色的bindingHandler

我对它进行了进一步的扩展,以处理哪个表头是活动的,然后在元素上应用一个
排序
类,以及一个
asc
。通过这种方式,您可以使用CSS向最终用户显示表头是否正在排序,以及是否设置为asc或desc

ko.bindingHandlers.sort = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {


        var asc = ko.observable(false);

        var value = valueAccessor();
        var prop = value.prop;
        var data = value.arr;

        if(!bindingContext.$data['currentClicked'])
        {
            bindingContext.$data['currentClicked'] = ko.observable();
        }


        var isActive = ko.computed(function()
        {
            return (bindingContext.$data['currentClicked']() === prop)
        });


        ko.applyBindingsToNode(element, {
                    css: {'sorting': isActive, 'asc': asc}
                }, bindingContext);


        element.onclick = function(){

            asc(!asc())

            bindingContext.$data['currentClicked'](prop);                       

            data.sort(function(left, right){
                var rec1 = left;
                var rec2 = right;

                if(!asc()) {
                    rec1 = right;
                    rec2 = left;
                }

                var props = prop.split('.');

                for(var i in props)
                {
                    var propName = props[i];
                    var parenIndex = propName.indexOf('()');

                    if(ko.isWriteableObservable(rec1[propName]))
                    {
                        rec1 = rec1[propName]();
                        rec2 = rec2[propName]();
                    } else {
                        rec1 = rec1[propName];
                        rec2 = rec2[propName];
                    }
                }

                return rec1 == rec2 ? 0 : rec1 < rec2 ? -1 : 1;
            });
        };
    }
};
ko.bindingHandlers.sort={
init:function(元素、valueAccessor、allBindingsAccessor、viewModel、bindingContext){
var asc=可观察的ko(假);
var value=valueAccessor();
var prop=value.prop;
变量