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
'IT' 카테고리의 다른 글
Debian / Ubuntu Docker 컨테이너에 로케일을 설정하는 방법은 무엇입니까? (0) | 2020.09.06 |
---|---|
명령 줄에서 여러 AWS 계정을 사용하는 방법은 무엇입니까? (0) | 2020.09.06 |
Bootstrap Carousel 이미지가 제대로 작동하지 않습니다. (0) | 2020.09.06 |
키보드 높이를 얻는 방법? (0) | 2020.09.06 |
Angular 2에서 CSS를 동적으로 업데이트 (0) | 2020.09.06 |