Как работает разбиение на страницы в системе API (интерфейс — angular2, а сервер — laravel5.4)?

У меня есть проект для бронирования отелей, интерфейс создан с использованием angular2, а серверная часть создана с использованием laravel. Это система API. У меня есть список таблиц в angular2. Для этого я получил данные о бронировании из laravel и привязал их к таблице angular, но я не знаю, как работает нумерация страниц через API. Первоначально я извлек и привязал только 15 данных. Как можно получить доступ к большему количеству данных, когда мы нажимаем на следующую страницу. Вот код для laravel angular.

Ларавел

public function index()
{
   $bookings = Booking::where('is_delete', 0)
            ->paginate(15);

   return response()->json(['bookingDetails' => $bookings], 200);
}

Угловой2

booking.service.ts

import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';

import { Bookings } from './booking';

import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import 'rxjs/Rx';
import { Observable } from "rxjs";

@Injectable()
export class BookingService {
    private headers = new Headers({'Content-Type': 'application/json'});
    private _url: string = 'http://cabinapi.app/api/bookings/';
    /*private _url: string = 'apidata/testData.json';*/
    constructor(private http: Http) { }

    getBooking(): Observable<any> {
        return this.http.get(this._url)
            .map((response: Response) => response.json().bookingDetails.data as Bookings[])
            .catch(this.handleError);
    }
    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
}

booking.component.ts

import { Component, OnInit } from '@angular/core';

import { BookingService } from './booking.service';
import { Bookings } from './booking';
@Component({
    selector: 'booking',
    templateUrl: './booking.component.html'
})
export class BookingComponent implements OnInit {
    bookings: Bookings[];
    constructor(private employeeService: BookingService) {}
    getBooking(): void {
        /*this.employeeService.getEmployee().then(employees => this.employees = employees);*/
        this.employeeService.getBooking().subscribe(bookings => this.bookings = bookings);
    }
    ngOnInit(): void {
        this.getBooking();
        setTimeout(function () {
            $(function() {
                $("#dataTable").DataTable();
            });
        }, 1000);
    }
}

person Sarath TS    schedule 12.06.2017    source источник


Ответы (2)


Вот как создать пользовательский интерфейс Angular с разбиением на страницы, который работает с родной системой разбиения на страницы Laravel:

Во-первых, чтобы помочь, создайте класс Booking и PaginatedBooking (мои заказы просты и имеют только описание — настраивайте по мере необходимости):

booking.model.ts:

export class Booking {
  id: number;
  description: string;
}

paginated-booking.model.ts: представляет данные разбиения на страницы, возвращаемые Laravel

import { Booking } from './booking.model'

export class PaginatedBooking {
  current_page: number;
  data: Booking[];
  from: number;
  last_page: number;
  next_page_url: string;
  path: string;
  per_page: number;
  prev_page_url: string;
  to: number;
  total: number;
}

Затем создайте свой сервис для получения данных бронирования с разбивкой на страницы. Добавьте функцию getBookingsAtUrl(url) — мы будем использовать ее позже, чтобы запрашивать определенные наборы данных разбиения на страницы из Laravel, когда вы нажимаете кнопки «предыдущий/следующий»:

booking.service.ts

export class BookingService {
    private bookingUrl: string = '/api/bookings'
    constructor(private http: Http) { }

    getBookings(): Promise<PaginatedBooking>{
        return this.http.get(this.bookingUrl)
        .toPromise()
        .then(response => response.json() as PaginatedBooking)
        .catch(this.handleError);
    }

    getBookingsAtUrl(url: string): Promise<PaginatedBooking>{
        return this.http.get(url)
        .toPromise()
        .then(response => response.json() as PaginatedBooking)
        .catch(this.handleError);
    }

    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
}

В своем компоненте внедрите ngOnInit(), чтобы получить исходные данные о бронировании. Затем реализуйте функцию getPrev() и функцию nextPage(), которые вызывают службу Bookings при нажатии этих кнопок:

booking.component.ts:

export class BookingComponent implements OnInit {
  bookings:PaginatedBooking;
  constructor(private service: NativeBookingService) { }

  ngOnInit() {
    this.service.getBookings().then(bookings=>this.bookings = bookings);
  }

  prevPage() {
    this.service.getBookingsAtUrl(this.bookings.prev_page_url).then(bookings=>this.bookings = bookings);
  }

  nextPage() {
    this.service.getBookingsAtUrl(this.bookings.next_page_url).then(bookings=>this.bookings = bookings);
  }
}

Наконец, ваш шаблон компонента:

booking.component.html:

<div *ngIf="bookings">
  <ul>
    <li *ngFor="let booking of bookings.data">{{booking.description}}</li>
  </ul>
  <p>Showing booking {{bookings.from}} to {{bookings.to}} of {{bookings.total}}</p>
  <p>Page {{bookings.current_page}} of {{bookings.last_page}}</p>
  <button (click)="prevPage()" [disabled]="!bookings.prev_page_url" >Prev</button>
  <button (click)="nextPage()" [disabled]="!bookings.next_page_url">Next</button> 
</div>

И это должно сделать это. Я опустил некоторые импорты для краткости. Настройте свой шаблон по мере необходимости. У меня есть пример проекта, который демонстрирует, как все это объединяется, но обратите внимание, что мои файлы Angular названы немного по-другому, и я добавил наивное состояние загрузки:

https://github.com/SpaceFozzy/laravel-angular-pagination

И вы можете посмотреть живую демонстрацию здесь.

Удачи!

person SpaceFozzy    schedule 18.06.2017

Классы результатов разбивки на страницы Laravel реализуют контракт интерфейса Illuminate\Contracts\Support\Jsonable и предоставляют метод toJson, поэтому очень легко преобразовать результаты разбивки на страницы в JSON. Вы можете просто вернуться из контроллера.

public function index()
{
   $bookings = Booking::where('is_delete', 0)
            ->paginate(15);

   return $bookings;
}

И результат должен быть примерно таким

{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "next_page_url": "http://example.app?page=2",
   "prev_page_url": null,
   "from": 1,
   "to": 15,
   "data":[
        {
            // Result Object
        },
        {
            // Result Object
        }
   ]
}

И вы просто можете реализовать процесс пагинации во внешнем интерфейсе.

person Vahe Galstyan    schedule 12.06.2017
comment
Спасибо за ваш ответ. Да, ответ становится таким, как вы упомянули. Но я сомневаюсь, как это работает во внешнем интерфейсе в соответствии с моим кодом, упомянутым в моем вопросе. - person Sarath TS; 15.06.2017