[javascript] 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;
}

결코 예쁘지는 않지만 “문자열 부정”입니다. 자바 스크립트에서 네이티브 객체 유형을 수정하는 데 어려움이 없다면 문자열 부정자를 추출하여 String.Prototype에 메서드로 추가하여 코드를 더 명확하게 만들 수 있습니다. 그러나 자바 스크립트에서 네이티브 객체 유형을 수정하면 예상치 못한 결과가 발생할 수 있으므로 수행중인 작업을 알고있는 경우에만이 작업을 수행하고 싶을 것입니다.


답변

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

이중 렌더링을 방지하려면 먼저 자동으로 정렬 한 다음 ‘재설정’을 트리거하십시오.

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 % 2FArray % 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 기능이 실행되고 컬렉션의 순서가 변경됩니다.

이 접근 방식을 숫자와 문자열로 테스트했으며 완벽하게 작동하는 것 같습니다.

나는이 문제로 여러 번 고생하고 일반적으로 해결 방법을 사용하기 때문에이 답변이 도움이되기를 바랍니다.