ng2-smart-table с подкачкой из back-end (Spring)

Я использую внутренний сервер (Java Spring), на котором включен пейджер. Я загружаю 100 записей на страницу по HTTP-вызову.

В сервисе angular2 он использует вызов API с «? Page = 1 & size = 100» в качестве начального вызова, тогда как на пейджере размера клиента он показывает 10 и перемещается до 10 страниц, что нормально. Но я не могу загрузить следующий фрагмент данных с сервера. Я проверил ServerDataSource и использовал .setPaging (1,100).

Как мне загрузить следующий фрагмент данных (2-200) и как этого добиться. Любые подсказки будут полезны.

@Injectable()
export class AmazonService extends ServerDataSource {

constructor(protected http: Http) {
    super(http);
}

public getAmazonInformation(page, size): Observable<Amazon[]> {

    let url = 'http://localhost:8080/plg-amazon?page=1&size=100';
    this.setPaging(1, 100, true);
    if (this.pagingConf && this.pagingConf['page'] && 
       this.pagingConf['perPage']) {
          url += 
       `page=${this.pagingConf['page']}&size=${this.pagingConf['perPage']}`;
}

return this.http.get(url).map(this.extractData).catch(this.handleError);
}

Спасибо!


person Sovan Misra    schedule 21.06.2017    source источник


Ответы (5)


Решил эту проблему с LocalDataSource.

HTML:

<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>

TS:

source: LocalDataSource = new LocalDataSource();
pageSize = 25;

ngOnInit() {
  this.source.onChanged().subscribe((change) => {
    if (change.action === 'page') {
      this.pageChange(change.paging.page);
    }
  });
}

pageChange(pageIndex) {
  const loadedRecordCount = this.source.count();
  const lastRequestedRecordIndex = pageIndex * this.pageSize;

  if (loadedRecordCount <= lastRequestedRecordIndex) {    
    let myFilter; //This is your filter.
    myFilter.startIndex = loadedRecordCount + 1;
    myFilter.recordCount = this.pageSize + 100; //extra 100 records improves UX.

    this.myService.getData(myFilter) //.toPromise()
      .then(data => {
        if (this.source.count() > 0){
          data.forEach(d => this.source.add(d));
          this.source.getAll()
          .then(d => this.source.load(d))
      }
        else
          this.source.load(data);
      })
  }
}
person boyukbas    schedule 10.04.2019
comment
Спасибо за пример. Как точно загрузить значения разбивки на страницы, когда localDataSource не завершен. Т.е. скажем, у меня есть 10 страниц из 25 элементов данных (всего 250 записей), я загружаю первые 50 при загрузке страницы и хочу показать пользователю 10 страниц в разбивке на страницы, поэтому, когда пользователь щелкает другую страницу, он динамически загружает данные, если их там нет. - person mumblesNZ; 17.01.2020
comment
эй, я использую твое решение, но у меня есть это property 'then' does not exist on type 'object ' - person naoval; 08.10.2020
comment
Я думаю, вам следует раскомментировать часть //.toPromise. Ошибка связана с вашей функцией getData. - person boyukbas; 08.10.2020

Попробуй выставить настройки смарт-таблицы вот так

<ng2-smart-table #grid [settings]="settings" ... >

И в вашем компоненте определите настройки, примерно так:

  public settings: TableSettings = new TableSettings();

  ngOnInit(): void {
      ...
    this.settings.pager.display = true;
    this.settings.pager.perPage = 100;
    ...
  }

person hamilton.lima    schedule 21.06.2017
comment
Спасибо, но это для настройки страницы на стороне клиента, которая будет отображать 100 записей на странице, которая есть в моем ответе на первый запрос, но в моей базе данных более 100 записей, которые я хочу загрузить кусками по 100. Мой вопрос заключался в том, как и где обновить URL-адрес http-запроса с помощью (page & size), когда мы дойдем до сотого элемента. - person Sovan Misra; 22.06.2017
comment
smart-table добавит параметры в запрос за вас :) взгляните на реализацию ServerDataSource, github.com/akveo/ng2-smart-table/blob/master/src/ , метод addPagerRequestOptions () - person hamilton.lima; 23.06.2017

Также, если вам нужно настроить запрос на бэкэнд, есть параметры конфигурации для ServerDataSource, который используется для получения / разбивки на страницы / сортировки данных.

введите описание изображения здесь

person Alex Efimov    schedule 16.08.2018

Когда у вас есть конечная точка для некоторого объекта в {endPointBase} / ng2-smart-table, где вы обрабатываете параметры запроса key_like (например: @Requestparam Сопоставление с данными Spring Пример ), вы можете использовать на стороне клиента:

export class SpringDataSource extends ServerDataSource {
    constructor(http: HttpClient, endPointBase: string) {
        const serverSourceConf = new ServerSourceConf();
        serverSourceConf.dataKey = 'content';
        serverSourceConf.endPoint = endPointBase + `/ng2-smart-table`;
        serverSourceConf.pagerLimitKey = 'size';
        serverSourceConf.pagerPageKey = 'page';
        serverSourceConf.sortFieldKey = 'sort';
        serverSourceConf.totalKey = 'totalElements';

        super(http, serverSourceConf);
    }

    protected addPagerRequestParams(httpParams: HttpParams): HttpParams {
        const paging = this.getPaging();
        return httpParams
            .set(this.conf.pagerPageKey, (paging.page - 1).toString())
            .set(this.conf.pagerLimitKey, paging.perPage.toString());
    }

    protected addSortRequestParams(httpParams: HttpParams): HttpParams {
        const sort: {field: string, direction: string}[] = this.getSort();

        sort.forEach((column) => {
            httpParams = httpParams.append(this.conf.sortFieldKey, `${column.field},${column.direction}`);
        });
        return httpParams;
    }
}
person amjr    schedule 09.04.2020
comment
Этот пример без кеширования. Но кеширование - это проблема, когда мы можем использовать сортировку и фильтрацию на основе запросов БД к большой таблице. 10 элементов быстро загружаются с сервера. И наш UX был улучшен за счет небольших страниц, полученных с сервера. - person amjr; 09.04.2020

Это мой способ решения всех этих проблем.

1. Убедитесь, что в Backend (API) включена функция cors, чтобы клиент мог отображать заголовок X-Pagination следующим образом:

app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders(new string[] { "X-Pagination"}));

2: HTML:

<ng2-smart-table [settings]="settings" [source]="source"></ng2-smart-table>

3: ОБСЛУЖИВАНИЕ:

getClients(pageNumber: number, pageSize: number): Observable<any> {
            const headers = new HttpHeaders({'Content-Type': 'application/json','Accept': 'application/json' });
            let params = new HttpParams();
            params = params.append('PageNumber',pageNumber.toString());
            params = params.append('PageSize',pageSize.toString());
            return this.http.get<ClientDto[]>(API_URL, {headers: headers, observe: "response" as "body",  responseType: "json", params} );
          }

4: TS:

export class ListClientComponent implements OnInit {

  source: LocalDataSource;
  pageSize = 30;
  currentPage = 1;
  showPerPage = 10;
  totalCount;
  constructor(private service: ClientService,private router: Router) {
    this.initData();
  }

  public settings = {
    mode: 'external', 
    pager:{
      display: true,
      perPage: this.showPerPage,
    },
    actions: {
      add:false,
      edit:true,
      delete:false
    },
        columns: {
      clientId: {
        title: 'CI',
      },
      name: {
        title: 'Name'
      },
      instagramName: {
        title: 'Instagram'
      },
      type: {
        title: 'Type'
      },
      phone: {
        title: 'Phone'
      },
      gender: {
        title: 'Gender'
      },
      age: {
        title: 'Age'
      },
      city: {
        title: 'City'
      },
      email: {
        title: 'Email'
      }
    },
  };

  ngOnInit() {
    this.initOnChagedData();
  }

  onEdit(event){
    console.log(event.data.clientId);
    this.router.navigate(['/clients/update-client/'+ event.data.clientId]) ;  
  }

  initData(){
    this.source = new LocalDataSource();
    this.service.getClients(this.currentPage, this.pageSize).subscribe( (result: HttpResponse<any>) => {
      if(!result){
        return;
      }
      this.source.load(result.body);
      this.totalCount = JSON.parse(result.headers.get("X-Pagination"));
      this.totalCount = this.totalCount["totalCount"];
      console.log(this.source.count());
    }
    )
  }

  initOnChagedData(){
    this.source.onChanged().subscribe((change) => {
      if (change.action === 'page') {
        this.pageChange(change.paging.page);
      }
    });
  }

  pageChange(pageIndex) {
    var getNew = pageIndex * this.showPerPage;
    if( getNew >= this.source.count() && getNew < this.totalCount){
      this.currentPage = this.currentPage + 1;
      this.service.getClients(this.currentPage, this.pageSize).subscribe( result => {
        if(!result){
          return;
        }
        result.body.forEach(element => {
          this.source.add(element);
        });
      })
    }
  }
}

Вы должны заметить, что pageSize = общие данные, которые мы извлекаем из серверной части и отображаем на странице = общие данные, которые мы показываем в таблице.

Алгоритм предназначен для извлечения из API только при необходимости, то есть, когда клиент достигает страницы, где данные заканчиваются в памяти, он запрашивает еще 30 данных, чтобы иметь еще 3 страницы, а также не забывает другие 3 которые уже извлекались раньше.

person OnlixProg779    schedule 03.06.2021