Пейджинг на стороне сервера для повышения производительности - PullRequest
0 голосов
/ 28 апреля 2018

Я следовал инструкциям Pagination для Angular, шаг за шагом в его документации, которая здесь https://www.npmjs.com/package/ngx-pagination. Моя нумерация страниц работает отлично, и у меня нет проблем с этим. Однако, поскольку я работаю с большим набором данных - я не хочу работать с полным набором в памяти, и мне нужен какой-то пейджинг на стороне сервера, когда сервер отправляет только одну страницу за раз. Как упоминалось в этой статье, я должен использовать totalItems параметр и использовать счетчик, но я не знаю как? Как мне установить total?

<table class='table' *ngIf="collection">
<tbody>
 <tr *ngFor="let item of collection | 
       paginate: { itemsPerPage: 10, currentPage: p, totalItems: total  }">
        <td>{{ item.id }}</td>
        <td>{{ item.name }}</td>
    </tr>
</tbody>

И мой WEB API выглядит так:

[HttpGet("[action]")]
public async Task<IEnumerable<MyClass>> MyMethod()
{
    int perPage = 10;
    int start = (page - 1) * perPage;
    int end = start + perPage;

    using (HttpClient client = new HttpClient())
    {
        client.BaseAddress = new Uri("externalAPI");
        MediaTypeWithQualityHeaderValue contentType =
            new MediaTypeWithQualityHeaderValue("application/json");
        client.DefaultRequestHeaders.Accept.Add(contentType);
        HttpResponseMessage response = await client.GetAsync(client.BaseAddress);
        string content = await response.Content.ReadAsStringAsync();
        List<MyClass> data = JsonConvert.DeserializeObject<List<MyClass>>(content);
        return data.Skip(start).Take(perPage).ToList();
    }
}

И

p: number = 1;
total: number;

http.get('url', {
    params: {
        page : this.p
   }
}).subscribe(result => {
    this.collections = result.json() as Collection[];
}, error => console.error(error));

1 Ответ

0 голосов
/ 28 апреля 2018

для разбивки на страницы на сервере вам нужно иметь две вещи:

  1. размер страницы или itemsPerPage в вашем случае
  2. pageNumber, который в основном ваш currentPage

Вам необходимо отправить эти два значения в ваш webapi, чтобы он знал, какие данные возвращать. Они станут параметрами вашего действия, и вы сможете передать их в webapi.

как вы разбиваете страницы в webapi, зависит от вашего кода. Если вы используете EntityFramework, это просто с методами Take и Skip. Если у вас есть хранимая процедура (например, T-SQL), вы можете сделать это с помощью Fetch и Offset.

Слово предостережения на pageNumber. Страница 1 в вашем пользовательском интерфейсе должна стать страницей 0 на стороне сервера, поэтому, когда ваш пользовательский интерфейс запрашивает страницу 1, это в основном страница 0 данных. Сторона пользовательского интерфейса становится стороной данных, так что вы, вероятно, передаете pageNumber - 1 к задней части. Просто имейте это в виду.

totalItems - это число, полученное из серверной части. Допустим, ваш веб-интерфейс возвращает разбитые на страницы данные, которые выглядят так:

public class myReturnedData
{
    public string someData1 { get;set; }
    public string someData2 { get;set }
}

ваш API возвращает список этого класса в основном.

На этом этапе создайте еще один объект, который выглядит следующим образом:

public class myPaginatedReturnedData
{
    public List<myReturnedData> { get; set; }

    public int TotalItemsCount { get; set; }
}

ваш интерфейс не может узнать, что такое общее количество, поскольку он получает только одну страницу данных, поэтому вам нужно получить это число из API, и это один из способов сделать это.

Итак, перед тем, как разбивать страницы на страницы на сервере, вы делаете общий подсчет своих элементов, затем разбиваете на страницы данные и, наконец, отправляете обратно оба этих элемента.

На внешней стороне у вас будут pageSize и totalItemsCount, и вы можете использовать их для подсчета количества индексов страниц, которые вы должны отобразить пользователю.

Если ваш pageSize равен 10, а totalItemsCount равен 55, тогда индекс вашей страницы будет от 1 до 6, а на странице 6 будет отображаться только 5 элементов. Вы можете легко написать метод на стороне клиента для этого расчета.

<- дополнительная информация ->

изменить это:

public async Task<IEnumerable<MyClass>> MyMethod()

до

public async Task<myPaginatedReturnedData> MyMethod()

Я в основном изменил ваш исходный возвращенный класс на новый в моем примере, который является вашей оберткой плюс значение totalCount.

Это позволяет вам установить значение в вашем интерфейсе, так как вы теперь возвращаете его вместе с вашими фактическими нумерованными данными.

На стороне клиента ответом API будет строка.

Вы можете разобрать строку ответа в объект JSON, используя что-то вроде

var apiData = JSON.parse(responseString)

Это дает вам объект, и вы можете получить доступ к своим данным оттуда.

...