2012-06-11 4 views
1

현재 활동/장소와 AsyncDataProvider를 사용하는 애플리케이션이 있습니다.Objectify/Google App Engine을 사용하여 AsyncDataProvider 사용/검색

지금 당장 액티비티가로드 될 때마다 요청 팩토리를 사용하여 데이터를 검색하고 (현재 많이는 아니지만 곧 대량의 데이터가 검색됩니다) DataGrid를 업데이트하기 위해 요청을 View로 전달합니다. 업데이트되기 전에 검색 상자를 기반으로 필터링됩니다. 지금

는 - 나는 다음과 같이 데이터 그리드를 업데이트 구현 : (이 코드가없는 예쁜)

private void updateData() { 
    final AsyncDataProvider<EquipmentTypeProxy> provider = new AsyncDataProvider<EquipmentTypeProxy>() { 

    @Override 
    protected void onRangeChanged(HasData<EquipmentTypeProxy> display) { 
     int start = display.getVisibleRange().getStart(); 
     int end = start + display.getVisibleRange().getLength(); 
     final List<EquipmentTypeProxy> subList = getSubList(start, end); 
     end = (end >= subList.size()) ? subList.size() : end; 
     if (subList.size() < DATAGRID_PAGE_SIZE) { 
     updateRowCount(subList.size(), true); 
     } else { 
     updateRowCount(data.size(), true); 
     } 
     updateRowData(start, subList); 
    } 

    private List<EquipmentTypeProxy> getSubList(int start, int end) { 
     final List<EquipmentTypeProxy> filteredEquipment; 
     if (searchString == null || searchString.equals("")) { 
     if (data.isEmpty() == false && data.size() > (end - start)) { 
      filteredEquipment = data.subList(start, end); 
     } else { 
      filteredEquipment = data; 
     } 
     } else { 
     filteredEquipment = new ArrayList<EquipmentTypeProxy>(); 
     for (final EquipmentTypeProxy equipmentType : data) { 
      if (equipmentType.getName().contains(searchString)) { 
      filteredEquipment.add(equipmentType); 
      } 
     } 
     } 
     return filteredEquipment; 
    } 
    }; 
    provider.addDataDisplay(dataGrid); 
} 

궁극적으로 - 내가 뭘하고 싶은 (처음에 필요한 데이터를로드 아니라 이 응용 프로그램의 기본 페이지 크기는 25입니다.

유감스럽게도, 현재 Google App Engine을 사용하고있는 Id에 대한 순서는 없습니다 (한 항목의 ID는 3이고 다음 항목은 4203입니다).

Objectify를 사용할 때 Google App Engine에서 데이터의 하위 집합을 가져 오는 가장 좋은 방법은 무엇입니까?

나는 오프셋과 한도를 사용하고 있지만 다른 스택 오버플로 게시 (http://stackoverflow.com/questions/9726232/achieve-good-paging-using-objectify) 기본적으로 비효율적이라고 말했다.

내가 찾은 최고의 정보는 다음 링크 (http://stackoverflow.com/questions/7027202/objectify-paging-with-cursors)입니다. 여기의 대답은 커서를 사용하는 것뿐만 아니라 비효율적이라고 말합니다. 또한 요청 팩토리를 사용하여 커서를 내 사용자 세션에 저장해야합니다 (잘못된 경우 나에게 알려주십시오).

현재 많은 데이터가있을 가능성이 없으므로 (앞으로 몇 달 동안 총 200 행이 될 수 있음) 일시적인 해킹으로 전체 세트를 클라이언트에게 되돌려 놓고 있습니다. - 이것이 최악이라는 것을 알고 있습니다. 방법은 그것을 할 수 있지만 다른 해킹 솔루션을 구현하는 시간을 낭비하기 전에 그것을 할 수있는 가장 좋은 방법에 대한 의견을 얻고 싶습니다. 현재이 작업을 읽을 때마다 읽은 모든 단일 게시물이이 작업을 수행 할 수있는 확실한 방법이 아닌 것처럼 보입니다.

내가하는 일에 대해서도 생각하고 있습니다. 현재 모든 데이터가 이미 클라이언트 측에 있기 때문에 현재 내 검색/페이지 로딩 속도가 빠릅니다. 검색 상자에 KeyUpEvent 핸들러를 사용하여 데이터를 필터링합니다. 서버에 전화하여이 속도를 유지할 방법이 없다고 생각합니다.이 문제에 대한 수용된 해결책이 있습니까?

고맙습니다.

답변

2

커서로 이동하십시오. 커서는 마지막 쿼리가 끝난 지점을 저장하고 거기에서 계속됩니다. 실제로 링크 한 대답은 커서 대 오프셋의 효율성을 논의하지 않습니다. (잘못된 설명이 있음)

커서와 함께 한계를 사용할 수 있습니다. 효율성에는 영향을 미치지 않습니다.

또한 커서는 cursor.toWebSafeString()을 통해 일련 번호를 지정하고 RPC를 통해 클라이언트로 보낼 수 있습니다. 이렇게하면 세션에 저장할 필요가 없습니다. 사실 fragment identifier (GWT 용어로 사용되는 히스토리 토큰)으로 사용할 수도 있습니다. 이렇게하면 결과 집합의 특정 "페이지"를 북마크 할 수 있습니다.

OTOH, 이미 쿼리 매개 변수를 알고 있다면 때 페이지를 (오프셋은 단지 제한 개체를 반환 비트, 그것 때문에 실제로로드 "비효율적"이며, 오프셋 + 제한 개까지 모든 엔티티를 위해, 당신을 청구합니다) 그러면 페이지 생성 시간에 쿼리를 수행하고 대신 RPC를 통해 쿼리를 호출합니다. 또한 데이터 수가 적은 경우 (< 1000) 페이지 html의 일부인 모든 엔티티 ID를 미리로드 할 수 있습니다.

+0

감사합니다. 정확히 커서를 serialize하고 RPC를 통해 클라이언트에 보내면 –

+0

이됩니다. RequestFactory를 사용할 때이 작업을 수행 할 수 있습니까? 그렇다면 어디서나이 예제가 있습니다. 클라이언트가 중단 된 부분을 정확하게 알 수 있으므로 언급 한 방식대로 처리하는 것이 좋을 것이라고 생각했습니다 (예를 들어, 활동이 처음부터 다시 시작하는 경우 사용자가 간단하게 우리가 정확한 포인트를 얻으려면 클라이언트에게 보낸 일련 화 된 커서를 사용하는 경우) - 나는 현재 요청 팩토리 설정에서이 작업을 수행하는 방법을 잘 모르겠습니다. –

관련 문제