2012-03-19 8 views
7

저는 Signalr 허브를 사용하여 서버의 이벤트를 구독하고 있습니다. 어떤 이벤트가 허브에 전달되어 성공적으로 Marionette CollectionView에 항목을 추가합니다. 이것은 차례로 테이블로 렌더링됩니다.백본에서 컬렉션을 역순으로 렌더링 할 수 있습니까?

이벤트 테이블은 기본적으로 블로터이므로 이벤트를 역순으로 수행하고 n 개 이상의 이벤트 만 유지하는 것이 바람직합니다.

백본이 컬렉션을 역순으로 '자동으로'다시 렌더링 할 수 있습니까?

답변

1

일반적으로 렌더링은 Backbone.View '하위 클래스'에서 수행됩니다. 그래서 당신은 같은 것을 가지고

render: function() { 
    this.collection.each(function(model) { 
    // some rendering of each element 
    }, this); 
} 

this.collection는 아마도 Backbone.Collection 서브 클래스를, 그리고 당신이 원하는대로 순서 그래서 당신은 그것을 얻기 위해 그 위에 underscore.js methods를 사용할 수 있습니다

this.collection.reverse().each(...) 
this.collection.sort(function(m) { ... }).each(...) 

등을

물론, 백엔드에서 하나의 요소를 얻고 있으며 모든 것을 다시 렌더링하지 않고 올바른 위치에 삽입하고 싶습니다! 따라서 그 경우에는 오래된 학교에 가서 rel 속성 또는 data 속성으로 정렬 키를 삽입하고 renderNewItem (또는 이와 유사한) 메소드에서 insertAfter 또는 이와 유사한 jQuery를 사용하십시오.

+2

reverse() - 메서드는 underscore.js 메서드에서 사용할 수 없습니다. – hbruce

+0

하하 좋은 지적! 그래도 내 답변의 초석은 아니지. 당신은 다른 접근법을 사용하여 그것을 뒤집을 수 있습니다 :'_.each (_.toArray (this.collection) .reverse(), function (m) {...});'. 또는 coffeescript를 사용하는 경우 -1 단계로 for 루프를 작성할 수 있습니다. – rfunduk

1

백본은 컬렉션을 정렬 된 순서로 자동 보관합니다. 기본값이 아닌 정렬을 사용하려면 컬렉션에 comparator() 함수를 정의하면 대신 해당 값이 사용됩니다. 비교기는 하나 또는 두 개의 인수 인 see the Backbone documentation을 사용할 수 있습니다.

그런 다음 컬렉션을 .each() 루프로 렌더링하면 올바른 순서로 컬렉션이 출력됩니다. 새로운 항목을 정렬 된 순서로보기에 추가하는 것은 당신에게 달려 있습니다.

+0

Dira, 좋은 지적으로 쉽게 사용할 수 있습니다. 하지만 궁극적으로 DOM을 올바른 위치에 가져와야합니다. –

+1

네, jquery의 nth-child와 after() 또는 before() – dira

1

설명에서와 같이 컬렉션을 역순으로 다시 렌더링 할 필요가 없습니다. 해당보기의 컬렉션에 add에 대한 이벤트를 추가하고 방금 추가 한 항목을 렌더링하고 테이블에 추가하는 함수를 호출하면됩니다. 백본 당신이 비교를 정의하면 @breischl 지적으로 수집, 분류 유지하지만 https://github.com/marionettejs/backbone.marionette/issues/78

에서이 주제에 대한 스레드가 있습니다

this.collection.on('add', this.addItem); 
8

, 마리오네트가 순서대로 자동 변경됩니다 CollectionView을 다시 렌더링하지 않습니다 . 사실, Marionette은 컬렉션의 add 이벤트를 청취하고 새 ItemView를 추가합니다.당신이 당신의 CollectionView 항상 시간의 역순으로 항목을 표시하려면, 당신은 새 항목은 다음과 추가, 다음 CollectionViewappendHtml 메소드를 오버라이드 (override) 대신 을 앞에 추가로 추가하려면

:

var MyCollectionView = Backbone.Marionette.CollectionView.extend({ 
    appendHtml: function(collectionView, itemView){ 
    collectionView.$el.prepend(itemView.el); 
    } 
}); 

의견에 언급 된 @dira와 같은 특정 위치에 삽입하려는 경우 siverman의 github 링크에 게시 된 솔루션이 있습니다. 편의를 위해 여기에 재현 한 내용입니다 (면책 조항 : 테스트하지 않았습니다. 아래 개인 코드) :

변경 appendHtml에 :

(function($) { 
    return jQuery.fn.insertAt = function(index, element) { 
    var lastIndex; 
    if (index <= 0) return this.prepend(element); 
    lastIndex = this.children().size(); 
    if (index >= lastIndex) return this.append(element); 
    return $(this.children()[index - 1]).after(element); 
    }; 
})(jQuery); 
+1

을 사용하면 marionette 2.x에서 appendHtml이 attachHtml로 변경되었습니다. 희망은 다른 사람들을 돕는다! 이것은 정확히 내 웹 애플 리케이션의 다른 로직에 대한 주문을 어지럽히 지 않고 컬렉션을 역순으로 표시해야하는 것이었다. – mix3d

11

는 역순으로 나는 보통 같은 구성을 사용에 컬렉션을 이동하십시오 :

appendHtml: function(collectionView, itemView) { 
    var itemIndex; 
    itemIndex = collectionView.collection.indexOf(itemView.model); 
    return collectionView.$el.insertAt(itemIndex, itemView.$el); 
} 

그리고 것은 insertAt 기능을 제공하기 위해 jQuery을 확장하는 다음과 같은 추가 :

_.each(collection.last(collection.length).reverse(), function(model){ }); 
0

다음과 같은 컬렉션에서 모델을 뒤집을 수 있습니다. 백본 컬렉션의 역 반복을 지원하지 않습니다

_(view.collection.models).reverse(); 
0

당신은이 작업을 수행 할 수 있습니다 가장 쉬운 방법은 컬렉션의 모델보다 인덱스가 작아지는 루프를 사용하는 것입니다.

for (var i = collection.length - 1; i >= 0; i--) { 
    var model = collection.models[i]; 

    // your logic 
} 

이 정렬 또는 밑줄을 사용하여 컬렉션을 반전으로 그 우아한 아니다 그러나의 performace 훨씬 낫다. 서로 다른 루프를 비교해보십시오. here 그냥 고전 대신 foreach를 작성하는 데 드는 비용을 알아야합니다.

0

으로 (그리고 자원의 단지 낭비 : 그래서 ... 당신은 lodash 대신 밑줄로 사용하는 경우

this.collection.models = this.collection.models.reverse()