2013-03-07 2 views
4

나는 방화범과 역화를 가지고 놀고 있습니다. example은 명시 적으로 말하지 않지만, Backbone.Firebase.Collection의 인스턴스를 인스턴스화 할 때 서버에서 데이터를로드한다는 것을 알아 냈습니다. 예 :서버에서 수집 한 백 파이어 수집이 언제 완료되는지 어떻게 알 수 있습니까?

var TodoList = Backbone.Collection.extend({ 
    model: Todo, 
    firebase: new Backbone.Firebase("https://<your-namespace>.firebaseio.com") 
}); 
var todos = new TodoList(); // fetches data 

검색이 언제 완료되는지 어떻게 알 수 있습니까?

+0

나는이 문제에 대한 올바른 대답은 정확히 무엇을하려고하는지에 달려 있다고 생각합니다. Kato는 다양한 옵션에 대한 탁월한 분석을 제공합니다. 컬렉션에 이벤트를 추가 할 때 단순히 객체를 렌더링하는 것과 달리 데이터가로드되는시기를 알고 싶은 이유에 대해 좀 더 자세히 설명해 주시겠습니까? – Anant

+0

항목 목록에서 임의 항목을 선택하고 있습니다. 목록을 사용할 수있는시기를 알아야합니다 ... – sprugman

+0

(목록이 자주 변경되지 않습니다.) – sprugman

답변

8

Backfire의 모델을 사용하여 상당히 광범위하게 작업 한 데 대해 여러 가지 생각을했습니다. 그들 중 일부가 프로젝트에 대한 좋은 아이디어를 줄 수 있기를 바랍니다. 이 초기에 나처럼 실시간 환경 모두의

첫째로 정신 모델을 변경

, "모든 데이터가로드 될 때"알 정신 나가,이 가정 당신을 괴롭히는. 우리는 현재 실시간 환경에 있습니다. 0부터 시작하여 업데이트로 제공되는 모든 레코드를 처리하십시오. 이렇게하면 주를 다루려는 많은 시간과 노력을 절약 할 수 있습니다.

게으른 렌더링 및 DOM 바인딩

지금 백본으로, 나는 종종 자신이 게으른 렌더링 할 싶은 찾을 수 있습니다.

  • 시작 데이터를 수집 즉시, 그러나이라고 렌더링 될 때까지 일부 데이터는
  • 을 나타날 때까지
  • 는 "로드"메시지를 표시
  • 을 표시하지 않습니다 : 그건 내가 논리적으로 다음과 같은 조건을 처리 할이다 몇 가지 기록이 서로 가까이 도착했을 때, 자주 데이터를 변경하기위한 모든 하나 하나 개

좋은 솔루션을 다시 렌더링하지 않는 것은 개별적으로 대신 DOM의 각 노드를 조작 Backbone.ModelBinder의 CollectionBinder tool, 모든 재 렌더링입니다 기록들. 사이트에는 많은 예제가 있으므로 여기서는 자세히 설명하지 않겠습니다. 신속하고 더러운 솔루션으로

디 바운스는

밑줄의 debounce 방법은 데이터 바인딩의 모든 복잡성을 필요로하지 않는 작은 규모의 DOM 조작을위한 훌륭한 솔루션입니다. 나에게 잘 작동하는 약 250 회의 대기 상태에서 디 바운스하면 데이터 변경시 항상 렌더링이 수행되지만 한 번에 많은 업데이트가 발생하면 한 번만 렌더링됩니다.

우리가 Backbone.Firebase.Collection를 확장 컬렉션을 만든 가정 할 때, 우리는 다음과 같이 수행 할 수 있습니다 A가로드 된 데이터에

기다릴 이연 사용

var View = Backbone.View.extend({ 

    initialize: function() { 
     this.listenTo(this.collection, 'add remove', _.debounce(_.bind(this.dataChanged, this), 250)); 
    }, 

    render: function() { 
     this._isRendered = true; 

     /* do all my rendering magic here */ 
    }, 


    dataChanged: function() { 
     // wait until render has been called at least once 
     // if so, re-render on any change 
     this._isRendered && this.render(); 
    } 
}); 

을 내 Backfire를 구현 한 후, 첫 번째로드시 알림을받는 상태 저장 메소드를 추가했습니다.jQuery의 Deferred 개체를 사용하여이 작업을 수행했습니다. 컬렉션은 sync 이벤트를 해고하는 그런 그냥 듣기 :

this.collection.once('sync', /* data is loaded */); 

중포 기지에 대한 좋은 점은 초기 Firebase.on가 ('child_added'...) 결과 (기존 레코드)에서 오는 경향이 하나의 멋진 큰 덩어리 - 하나씩. 추가 보너스로, debump를 사용하여 초기 덩어리가 완료된 후 "로드 된"메소드를 실행 시키므로 하나의 레코드를 얻지 못하고로드 된 호출을받지 못하고 일련의 업데이트를 위해 즉시 조치를 취해야합니다. 이 구현 고유의 것입니다 때문에

, 여기 조금 추상적 될거야,하지만이 그것의 요점입니다 :

// inside my wrapper for Backbone.Firebase.Collection 
this.ready = $.Deferred(); 

// debounce our ready listener so it fires on the tail end of 
// the initial update clump which reduces the number of update 
// calls on the initial load process considerably 
this.readyFn = _.debounce(this.ready.resolve, 250); 

// start monitoring for the first series of updates 
// this would need to be invoked before the sync is established 
this.on('add', this.readyFn); 

// wait for the data to come in 
this.ready.always(_.bind(function() { 
    // when the ready promise is fulfilled, we can turn off the listener 
    this.off('add', this.readyFn); 

    // this is where we trigger the listener event used above 
    this.trigger('sync'); 
}, this)); 

내가주의이 솔루션을 사용하십시오. 대부분의 경우 초기로드를 잊어 버리고 모든 것을 비어있는 상태로 초기화 한 다음 모든 것을 업데이트로 처리하여 작업을 크게 단순화 할 수 있습니다.

데이터가 없으면 (시작 지침과 같은) 대체보기를 표시해야하는 경우에만이 기능을 사용합니다.

1

여기에 내가 알아 낸 하나의 방법입니다 - 컬렉션 내부의 중포 기지 객체를 사용

todos.firebase.on('value', function(snapshot){ 
    // do stuff 
}); 

가장 좋은 방법인가요?

+0

이것은 원하는 동작을 가지며 Firebase로 직접 작업 할 때 권장되는 방법입니다. 나는 그것이 역효과를 통해이 기능을 노출하는 가장 좋은 방법인지는 모르겠다. 조사하겠습니다. –

+0

그것은 새는 추상화를 깨고있는 것처럼 느껴집니다 ... – sprugman