2013-06-22 2 views
1

При обновлении данных внутри модели можно сохранить порядок сортировки (jsfiddle в конце)? У меня есть следующий код:Сохранение и намек на порядок сортировки при обновлении данных?

<table> 
    <thead> 
    <tr> 
     <th data-bind="sort: { arr: Records, prop: 'Name' }">Name</th> 
     <th data-bind="sort: { arr: Records, prop: 'Number' }">Number</th> 
     <th data-bind="sort: { arr: Records, prop: 'Desc' }">Description</th> 
    </tr> 
    </thead> 
    <tbody data-bind="foreach: Records"> 
    <tr> 
     <td data-bind="text: Name"></td> 
     <td data-bind="text: Number"></td> 
     <td data-bind="text: Desc"></td> 
    </tr> 
    </tbody> 
</table> 
<button data-bind="click: changeMe">Remove</button> 
<button data-bind="click: resetMe">Reset</button> 

Теперь сама сортировка реализуется с помощью bindingHandlers из этого original post:

var recs = []; 

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; 
      if(asc){ 
       data.sort(function(left, right){ 
        return left[prop] == right[prop] ? 0 : left[prop] < right[prop] ? -1 : 1; 
       }); 
      } else { 
       data.sort(function(left, right){ 
        return left[prop] == right[prop] ? 0 : left[prop] > right[prop] ? -1 : 1; 
       }); 
      } 
     } 
    } 
}; 

function ViewModel(){ 
    var self = this; 
    self.Records = ko.observableArray(); 

    self.changeMe = function() { 
     self.Records.pop() 
    } 

    self.resetMe = function() { 
     var recs = [] 
     recs.push({Name: 'Bob', Number: 1, Desc: 'I am awesome'}); 
     recs.push({Name: 'Joe', Number: 2, Desc: 'Another description'}); 
     recs.push({Name: 'Mitch', Number: 3, Desc: 'Something'}); 
     recs.push({Name: 'Steven', Number: 4, Desc: 'Yo'}); 
     self.Records(recs); 
    } 
} 

var viewModel = new ViewModel(); 
recs.push({Name: 'Bob', Number: 1, Desc: 'I am awesome'}); 
recs.push({Name: 'Joe', Number: 2, Desc: 'Another description'}); 
recs.push({Name: 'Mitch', Number: 3, Desc: 'Something'}); 
recs.push({Name: 'Steven', Number: 4, Desc: 'Yo'}); 
recs.push({Name: 'Robin', Number: 6, Desc: 'Hello'}); 
recs.push({Name: 'Batman', Number: 7, Desc: 'Description'}); 
recs.push({Name: 'John', Number: 5, Desc: 'Ok'}); 
viewModel.Records(recs); 
ko.applyBindings(viewModel); 

Например, рассмотрим этот JSFiddle и следующий ряд взаимодействий:

  • Нажмите на столбец, чтобы строки отсортировались по этому столбцу. Дважды нажмите «Номер», чтобы отсортировать его в порядке убывания.
  • Теперь нажмите «Сброс», чтобы имитировать вызов ajax (т. Е. Предположим, что я обновляю модель). Теперь порядок сортировки восстанавливается в оригинале.

Как сохранить порядок сортировки, т. Е. Помнить, что его следует сортировать по «Число» в порядке убывания? И, конечно, покажите это каким-то образом рядом с колонкой? Нечто похожее на то, как это делает datatables (обратите внимание на стрелки вверх и вниз рядом с каждым именем столбца).

Любые предложения?

+0

может быть, посмотрим на решение, которое я предложил вам? – AntouanK

ответ

0

Сделано, но должен быть лучший способ.

Дело в том, что я сделал флаг dataUpdated, поэтому каждый раз, когда данные обновляются, вы сортируете их снова. Кроме того, я держу в наблюдаемом объекте «пропеллер» и «порядка», так что вы можете делать такие вещи, когда они изменяются (есть значок со стрелкой, например, и изменить его в соответствии с заказом)

Проверьте это

->http://jsfiddle.net/blackjim/xgEdg/15/

var recs = []; 
ko.bindingHandlers.changed = { 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 

     if(viewModel.dataUpdated()){ 
      console.log('data updated, sorting...'); 
      sortThis(viewModel.Records,viewModel.sortData().order,viewModel.sortData().col); 
     } 
     viewModel.dataUpdated(false); 
    } 
} 

ko.bindingHandlers.sort = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var order = 'none'; // initial order status for this column 

     if(!viewModel.Records.dataSort){ 
      viewModel.Records.dataSort = { col: 'none', order: 'none' }; 
     } 

     element.style.cursor = 'pointer'; 
     element.sortAsc = element.sortAsc || false; 

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

      // sortData updated 
      viewModel.sortData({ 
       col: prop, 
       order: order = (order === 'asc' ? 'desc' : 'asc') 
      }); 

      sortThis(data, order, prop); 
     } 
    } 
}; 

// function for sorting the observable array 
function sortThis(data, order, prop){ 

    if (order === 'asc') { 
     data.sort(function (left, right) { 
      return left[prop] == right[prop] ? 0 : left[prop] < right[prop] ? -1 : 1; 
     }); 
    } else { 
     data.sort(function (left, right) { 
      return left[prop] == right[prop] ? 0 : left[prop] > right[prop] ? -1 : 1; 
     }); 
    } 
} 

function ViewModel() { 
    var self = this; 

    self.Records = ko.observableArray(); 
    self.sortData = ko.observable({ 
     col: "none", 
     order: "none" 
    }); 
    self.dataUpdated = ko.observable(false); // flag for data updating 

    self.changeMe = function() { 
     self.Records.pop(); 
    } 

    self.resetMe = function() { 

     self.Records.removeAll(); 
     self.Records.push({ 
      Name: 'Bob', 
      Number: 1, 
      Desc: 'I am awesome' 
     }); 
     self.Records.push({ 
      Name: 'Joe', 
      Number: 2, 
      Desc: 'Another description' 
     }); 
     self.Records.push({ 
      Name: 'Mitch', 
      Number: 3, 
      Desc: 'Something' 
     }); 
     self.Records.push({ 
      Name: 'Steven', 
      Number: 4, 
      Desc: 'Yo' 
     }); 
     // trigger the dataUpdated 'event' 
     self.dataUpdated(true); 

    } 
} 

var viewModel = new ViewModel(); 

recs.push({ 
    Name: 'Bob', 
    Number: 1, 
    Desc: 'I am awesome' 
}); 
recs.push({ 
    Name: 'Joe', 
    Number: 2, 
    Desc: 'Another description' 
}); 
recs.push({ 
    Name: 'Mitch', 
    Number: 3, 
    Desc: 'Something' 
}); 
recs.push({ 
    Name: 'Steven', 
    Number: 4, 
    Desc: 'Yo' 
}); 
recs.push({ 
    Name: 'Robin', 
    Number: 6, 
    Desc: 'Hello' 
}); 
recs.push({ 
    Name: 'Batman', 
    Number: 7, 
    Desc: 'Description' 
}); 
recs.push({ 
    Name: 'John', 
    Number: 5, 
    Desc: 'Ok' 
}); 
viewModel.Records(recs); 
ko.applyBindings(viewModel); 
Смежные вопросы