IT

Backbone.js로 정렬 순서 반전

lottoking 2020. 9. 6. 10:18
반응형

Backbone.js로 정렬 순서 반전


함께 Backbone.js I의 한 비교기 기능을 설정 컬렉션을 얻었다 . 모델을 멋지게 정렬하고 순서를 바꾸고 싶습니다.

모델을 오름차순이 아닌 내림차순으로 구매해야해야합니까?


음, 비교기에서 음수 값을 반환 할 수 있습니다. 예를 들어 Backbone 사이트의 예제를 가져 오는 순서를 바꾸고 다음과 같이 보일 것입니다.

var Chapter  = Backbone.Model;
var chapters = new Backbone.Collection;

chapters.comparator = function(chapter) {
  return -chapter.get("page"); // Note the minus!
};

chapters.add(new Chapter({page: 9, title: "The End"}));
chapters.add(new Chapter({page: 5, title: "The Middle"}));
chapters.add(new Chapter({page: 1, title: "The Beginning"}));

alert(chapters.pluck('title'));

개인적으로 여기에 거기 솔루션 중 어느 것도 만족스럽지 솔루션.

  • -1로 곱하기 솔루션은 정렬 유형이 숫자가 아닌 경우 작동하지 않습니다. 이 문제를 해결하는 방법이 ( 예를 들어 호출 하여) 상황을 해결하는 방법 입니다. 정렬되는 필드의 특정 유형에 대해 걱정할 필요없이 모든 종류의 방향을 바꾸는 방법을 원합니다.Date.getTime()

  • 향상된 솔루션의 경우 한 번에 한 문자 씩 업그레이드를 구성하는 것이 성능 병목 현상처럼. 특히 많은 경우 더욱 그렇습니다.

다음은 날짜 및 숫자 필드에 대해 잘 작동하는 솔루션입니다.

다음과 같이 sortBy 함수의 먼저 결과를 반전하는 비교기를 선언합니다.

function reverseSortBy(sortByFunction) {
  return function(left, right) {
    var l = sortByFunction(left);
    var r = sortByFunction(right);

    if (l === void 0) return -1;
    if (r === void 0) return 1;

    return l < r ? 1 : l > r ? -1 : 0;
  };
}

이제 정렬 방향을 바꾸려면 다음과 같이하면됩니다.

var Chapter  = Backbone.Model;
var chapters = new Backbone.Collection;

// Your normal sortBy function
chapters.comparator = function(chapter) {
  return chapter.get("title"); 
};


// If you want to reverse the direction of the sort, apply 
// the reverseSortBy function.
// Assuming the reverse flag is kept in a boolean var called reverseDirection 
if(reverseDirection) {
   chapters.comparator = reverseSortBy(chapters.comparator);
}

chapters.add(new Chapter({page: 9, title: "The End"}));
chapters.add(new Chapter({page: 5, title: "The Middle"}));
chapters.add(new Chapter({page: 1, title: "The Beginning"}));

alert(chapters.pluck('title'));

이것이 작동하는 이유 Backbone.Collection.sort는 정렬 함수에 두 개의 인수가있는 경우 다르게 작동하기 때문입니다. 이 경우 비교기가에 전달 된 것과 동일한 방식으로 작동합니다 Array.sort. 이 솔루션은 단일 인수 sortBy 함수를 두 개의 인수 비교기로 조정하고 결과를 사용하는 방식으로 작동합니다.


Backbone.js의 컬렉션 비교기는 Underscore.js 메소드 _.sortBy에 의존합니다. sortBy가 구현되는 방식은 일반적으로 사용되는 방식으로 javascript .sort ()를 ""합니다. 결국 단순한 부정은 결국 NaN을 반환하고 정렬을 중단합니다.

알파벳 역순 정렬과 같이 많은 것을 사용하여 역 정렬을 수행해야하는 경우 다음과 같은 작업을 수행해야합니다.

comparator: function (Model) {
  var str = Model.get("name");
  str = str.toLowerCase();
  str = str.split("");
  str = _.map(str, function(letter) { 
    return String.fromCharCode(-(letter.charCodeAt(0)));
  });
  return str;
}

하지만 예쁘지는 않지만 "문자열 부정"입니다. 자바 확장에서 코드를 명확하게 만들 수 있습니다. 그러나 자바는 알고있는 작업 유형을 수정하면 예상치 못한 결과가있을 수 있으므로 수행중인 작업을 수행하고 싶을 것입니다.


내 해결책은 정렬 후 결과를 뒤집는 것입니다.

이중 설치를 방지 먼저 자동으로 정렬 한 다음 '재설정'을 트리거하십시오.

collections.sort({silent:true})
collections.models = collections.models.reverse();
collections.trigger('reset', collections, {});

현재 데이터를 반환하는 대신 역 전례 값을 반환하도록 비교 함수를 수정하십시오. http://documentcloud.github.com/backbone/#Collection-comparator의 일부 코드

예 :

var Chapter  = Backbone.Model;
var chapters = new Backbone.Collection;

/* Method 1: This sorts by page number */
chapters.comparator = function(chapter) {
  return chapter.get("page");
};

/* Method 2: This sorts by page number in reverse */
chapters.comparator = function(chapter) {
  return -chapter.get("page");
};

chapters.add(new Chapter({page: 9, title: "The End"}));
chapters.add(new Chapter({page: 5, title: "The Middle"}));
chapters.add(new Chapter({page: 1, title: "The Beginning"}));

다음은 나를 위해 잘 작동했습니다.

comparator: function(a, b) {
  // Optional call if you want case insensitive
  name1 = a.get('name').toLowerCase();
  name2 = b.get('name').toLowerCase();

  if name1 < name2
    ret = -1;
  else if name1 > name2
    ret = 1;
  else
    ret = 0;

  if this.sort_dir === "desc"
    ret = -ret
  return ret;
}

collection.sort_dir = "asc";
collection.sort(); // returns collection in ascending order
collection.sort_dir = "desc";
collection.sort(); // returns collection in descending order

Backbone 비교기 함수가 JavaScript Array.prototype.sort () 함수를 사용하거나 모방하는 곳을 읽었습니다. 즉, 컬렉션에있는 각 모델의 정렬 순서를 결정하기 위해 1, -1 또는 0을 사용합니다. 이것은 업데이트되고 컬렉션은 비교 기반으로 올바른 순서로 유지됩니다.

Array.prototype.sort ()에 대한 정보는 다음에서 사용할 수 있습니다 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort?redirectlocale=en-US&redirectslug = JavaScript % 2FReference % 2FGlobal_Objects % 2Frray % 2Fsort

이 질문에 대한 많은 답변은 페이지로 방법하기 직전에 뒤집습니다. 이것은 딱이지 않습니다.

Mozilla에 대한 위의 가이드를 가이드로 사용하여 코드를 사용하여 내 컬렉션을 다음 역순으로 정렬 할 수 있습니다. 그런 다음 컬렉션을 현재 순서대로 페이지에 배포하고 순서를하기 위해 플래그 (reverseSortDirection)를 사용할 수 있습니다. .

//Assuming this or similar will be in your Backbone.Collection.
sortKey: 'id', //The field name of the item in your collection

reverseSortDirection: false,

comparator: function(a, b) {

  var sampleDataA = a.get(this.sortKey),
      sampleDataB = b.get(this.sortKey);

      if (this.reverseSortDirection) {
        if (sampleDataA > sampleDataB) { return -1; }
        if (sampleDataB > sampleDataA) { return 1; }
        return 0;
      } else {
        if (sampleDataA < sampleDataB) { return -1; }
        if (sampleDataB < sampleDataA) { return 1; }
        return 0;
      }

},

두 모델을 비교기, 컬렉션 또는 모델 변경시 compartor 기능이 실행되고 컬렉션의 순서가 변경됩니다.

이 접근 방식을 숫자와 호스트로 테스트 완벽하게 작동하는 것입니다.

나는이 문제로 여러 번 어려움을 사용하기 때문에 일반적으로 해결 방법을 사용하기 때문에 해결 방법이 있습니다.


이 sortBy 메서드를 재정 의하여 수행 할 수 있습니다. 다음은 예입니다.

var SortedCollection = Backbone.Collection.extend({

   initialize: function () {
       // Default sort field and direction
       this.sortField = "name";
       this.sortDirection = "ASC";
   },

   setSortField: function (field, direction) {
       this.sortField = field;
       this.sortDirection = direction;
   },

   comparator: function (m) {
       return m.get(this.sortField);
   },

   // Overriding sortBy (copied from underscore and just swapping left and right for reverse sort)
   sortBy: function (iterator, context) {
       var obj = this.models,
           direction = this.sortDirection;

       return _.pluck(_.map(obj, function (value, index, list) {
           return {
               value: value,
               index: index,
               criteria: iterator.call(context, value, index, list)
           };
       }).sort(function (left, right) {
           // swap a and b for reverse sort
           var a = direction === "ASC" ? left.criteria : right.criteria,
               b = direction === "ASC" ? right.criteria : left.criteria;

           if (a !== b) {
               if (a > b || a === void 0) return 1;
               if (a < b || b === void 0) return -1;
           }
           return left.index < right.index ? -1 : 1;
       }), 'value');
   }

});

따라서 다음과 같이 사용할 수 있습니다.

var collection = new SortedCollection([
  { name: "Ida", age: 26 },
  { name: "Tim", age: 5 },
  { name: "Rob", age: 55 }
]);

//sort by "age" asc
collection.setSortField("age", "ASC");
collection.sort();

//sort by "age" desc
collection.setSortField("age", "DESC");
collection.sort();

이 솔루션은 필드 유형에 의존하지 않습니다.


// For numbers, dates, and other number-like things
var things = new Backbone.Collection;
things.comparator = function (a, b) { return b - a };

// For strings
things.comparator = function (a, b) {
  if (a === b) return 0;
  return a < b ? -1 : 1;
};

현재 주문을 단순히 뒤집고 싶은 사람들을위한 정말 간단한 해결책이 있습니다. 열을 두 방향으로 정렬 할 수있는 테이블이있는 경우 유용합니다.

collection.models = collection.models.reverse()

테이블 케이스 (coffeescript)에 관심이 있다면 다음과 같이 결합 할 수 있습니다.

  collection.comparator = (model) ->
    model.get(sortByType)

  collection.sort()

  if reverseOrder
    collection.models = collection.models.reverse()

ID의 역순 :

comparator: function(object) { return (this.length - object.id) + 1; }

테이블에 모델을 표시하고 있다는 점에서 약간 다른 요구 사항이 있었는데, 모든 collumn (모델 속성)과 오름차순 또는 내림차순으로 정렬 할 수 있기를 원했습니다.

모든 경우 (값은 문자열, 빈 문자열, 날짜, 숫자가 될 수있는 경우)를 처리하는 데 상당한 양의 작업이 필요했습니다. 그러나 이것은 매우 비슷하다고 생각합니다.

    inverseString: function(str)
    {
        return str.split("").map(function (letter) { return String.fromCharCode(-(letter.charCodeAt(0))); }).join("");
    }
    getComparisonValue: function (val, desc)
    {
        var v = 0;
        // Is a string
        if (typeof val === "string")
        {
            // Is an empty string, upgrade to a space to avoid strange ordering
            if(val.length === 0)
            {
                val = " ";
                return desc ? this.inverseString(val) : val;
            }                

            // Is a (string) representing a number
            v = Number(val);
            if (!isNaN(v))
            {
                return desc ? -1 * v : v;
            }
            // Is a (string) representing a date
            v = Date.parse(val);
            if (!isNaN(v))
            {
                return desc ? -1 * v : v;
            }
            // Is just a string
            return desc ? this.inverseString(val) : val;
        }
        // Not a string
        else
        {
            return desc ? -1 * val : val;
        }
    },

사용하다:

    comparator: function (item)
    {
        // Store the collumn to 'sortby' in my global model
        var property = app.collections.global.get("sortby");

        // Store the direction of the sorting also in the global model
        var desc = app.collections.global.get("direction") === "DESC";

        // perform a comparison based on property & direction
        return this.getComparisonValue(item.get(property), desc);
    },

완료시 모델 배열을 반전시키기 위해 정렬 기능을 오버로딩했습니다. 또한 반전이 완료 될 때까지 '정렬'이벤트 트리거를 보류했습니다.

    sort : function(options){

        options = options || {};

        Backbone.Collection.prototype.sort.call(this, {silent:true});
        this.models.reverse();

        if (!options.silent){
            this.trigger('sort', this, options);
        }

        return this;
    },

최근에이 문제가 발생하여 rsort 메서드를 추가하기로 결정했습니다.

    Collection = Backbone.Collection.extend({
            comparator:function(a, b){
                return a>b;
            },
            rsort:function(){
                var comparator = this.comparator;

                this.comparator = function(){
                    return -comparator.apply(this, arguments);
                }
                this.sort();

                this.comparator = comparator;

            }
    });

누군가가 유용하다고 생각하기를 바랍니다.


UnderscoreJS를 사용하여 컬렉션의 모델을 역 정렬하는 빠르고 쉬운 방법입니다.

 var reverseCollection = _.sortBy(this.models, function(model) {
   return self.indexOf(model) * -1;
 });

참고 URL : https://stackoverflow.com/questions/5013819/reverse-sort-order-with-backbone-js

반응형