2014-01-15 2 views
3

이것은 원래 discuss.emberjs.com에 게시되었습니다. 참조 : http://discuss.emberjs.com/t/what-is-the-proper-use-of-store-filter-store-find-for-infinite-scrolling/3798/2Ember-Data에서 store.filter/store.find를 사용하여 무한 스크롤을 구현하는 방법은 무엇입니까?

하지만이 사이트는 나날이 나올 수 있기를 기대하면서 요즘 콘텐츠의 품질이 악화되고 악화되는 것처럼 보입니다.

의도 : 무한 스크롤을 구현하는 ember-data를 사용하여 ember에 페이지를 빌드하십시오.

배경 기술 : 엠 데이터, 특히 store.filter 및 store.find 방법에 emberjs.com의 API 문서 기준 (참고 : http://emberjs.com/api/data/classes/DS.Store.html#method_filter)을 난에 대한 경로의 모델 후크를 설정할 수 있어야 상점 필터 조작 약속. 약속의 응답은 필터 함수로 필터링 된 항목의 배열 인 필터링 된 레코드 배열이어야하며, 새 항목이 저장소에 푸시 될 때마다 지속적으로 업데이트되는 것으로 가정합니다. 이것을 store.find 메소드와 결합하면 항목을 상점에 넣을 수 있습니다. filteredRecordArray가 새 항목으로 자동 업데이트되어 모델을 업데이트하고 페이지에 새 항목을 표시해야합니다.

예를 들어 질문 경로, 컨트롤러 및 질문 유형의 모델이 있다고 가정합니다. 그런 다음

App.QuestionsRoute = Ember.Route.extend({ 
    model: function (urlParams) { 
     return this.get('store').filter('question', function (q) { 
      return true; 
     }); 
    } 
}); 

우리는이 관계없이이 방법은 것 그것이 스크롤 이벤트를 감지되거나 사용자가 명시 적으로 더로드 클릭 여부를 일부 이벤트/액션에 의해 트리거 될 수 store.find 호출이 어떤 방법으로 컨트롤러를 가지고 더 많은 질문을로드하려면 호출해야합니다. 예 :

App.QuestionsController = Ember.ArrayController.extend({ 
    ... 
    loadMore: function (offset) { 
     return this.get('store').find('question', { skip: currentOffset}); 
    } 
    ... 
}); 

그리고 항목을 렌더링 할 수있는 템플릿 :

... 
{{#each question in controller}} 
    {{question.title}} 
{{/each}} 
... 

공지 사항,이 방법으로 우리가 하지 명시 적으로 호출 store.find 약속에 기능을 추가해야 할 것을를 this.get('model').pushObjects(questions); 사실 필터 레코드 배열을 이미 모델에 반환하면이를 수행하려고 시도하면 작동하지 않습니다. 모델의 내용을 수동으로 관리하거나 엠버 데이터가 작업을 수행하게하고 엠버 데이터가 그 작업을하도록하고 싶습니다. 이것은 매우 깨끗한 API입니다. 그러나, 내가 쓰는 방식대로 작동하지 않는 것 같습니다. 문서를 기반으로 나는 틀린 것을 볼 수 없다.

Chrome의 Ember-Inspector 도구를 사용하면 두 번째 찾기 호출의 새로운 질문이 '질문'유형 아래 상점에로드되지만 경로를 변경하고 돌아올 때까지 페이지가 새로 고침되지 않음을 알 수 있습니다. 그것은 단순히 관측자들에게 문제가되는 것 같아서 Ember-Data에서 이것이 버그라고 생각하게 만들었지 만 Ember-Data를 사용하고 있는지를 물어볼 때까지 그런 결론에 도달하고 싶지 않았습니다. 의도 한대로 데이터.

누군가가 무엇이 잘못되었는지 정확히 알지 못하지만 store.push/pushMany를 사용하여이 시나리오를 jsbin에서 다시 작성하는 방법도 알고 있다면 도움이 될 것입니다. 나는 상점에서 하위 레벨 메소드를 사용하는 방법에 익숙하지 않다.

도움을 많이 받으실 수 있습니다.

답변

0

방금이 패턴을 직접 만들었지 만 store.filter()를 사용하지 않고 "전통적인"방식으로 만들었습니다.

내가 라우터 자체에 "loadMore"일부 관리 : 이미 (I 논의에 대한 게시물에 표시되는 내용에서) 전통적인 방법을 시도하기 때문에

actions: { 
    loadMore: function() { 
     var model = this.controller.get('model'), route = this; 
     if (!this.get('loading')) { 
      this.set('loading', true); 
      this.store.find('question', {offset: model.get('length')}).then(function (records) { 
       model.addObjects(records); 
       route.set('loading', false); 
      }); 
     } 
    } 
} 

를, 그것의 핵심 부분을 것 같다 이전처럼 pushObjects() 대신 addObjects()를 사용하십시오. 내가 지금은 대한 좋은 로더를 얻을 수 있도록 컨트롤러에 로딩 속성을 이동 찾고

didInsertElement: function() { 
    var controller = this.get('controller'); 
    $(window).on('scroll', function() { 
     if ($(window).scrollTop() > $(document).height() - ($(window).height()*2)) { 
      controller.send('loadMore'); 
     } 
    }); 
}, 
willDestroyElement: function() { 
    $(window).off('scroll'); 
} 

: 기록을 위해

, 여기에 loadMore 액션을 트리거 내보기의 관련 부분입니다 사용자.

관련 문제