axios-on-rails, как запросить набор записей - PullRequest
0 голосов
/ 08 октября 2018

Я создаю приложение в Rails с интерфейсом ReactJS.В моем внешнем интерфейсе я использую пакет пряжи axios-on-rails, чтобы выполнять все свои запросы к моему Rails api back-end.

Вот что я пытаюсь сделать: для главной страницы сайта я хочу реализовать функцию бесконечной прокрутки.Чтобы это работало хорошо, мне нужно иметь возможность запрашивать небольшие наборы записей, пока страница продолжает прокручиваться.Единственный способ, которым я знаю, как передавать записи в мой интерфейс, это использовать:

axios.get('/posts.json')
  .then((response) => {
    ...
  })
  .catch(error => console.log(error));

Это возвращает ВСЕ сообщения, хотя, в конечном счете, будет тысячи.Я не хочу, чтобы это случилось.Так как мне изменить этот запрос так, чтобы я получал только первые 20 записей или около того?

Подробности ответа

Хорошо, поэтому я еще раз взглянул на нумерацию страниц как @Гаган Гупта предложил и через несколько часов заставил его работать.Вот что я сделал.

yarn add react-infinite-scroll, чтобы получить необходимый компонент.

Для своего компонента подачи я сделал ...

import React from 'react';
import Post from './Post';
import { connect } from 'react-redux';
import { loadPosts } from '../actions/posts';
import InfiniteScroll from 'react-infinite-scroller';
import axios from 'axios-on-rails';

const node = document.getElementById('owc_feed_payload');
const numberOfPosts = JSON.parse(node.getAttribute('number_of_posts'));

class Feed extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      posts: props.posts,
      hasMoreItems: true,
      page: 1
    };
  }

  componentDidUpdate(prevProps) {
    if (this.props !== prevProps) {
      this.setState({ posts: this.props.posts, hasMoreItems: this.props.hasMoreItems });
    }
  }

  loadMore = (page) => {
    axios.get('/posts.json', {
      params: { page: page }
    })
      .then((response) => {
        console.log(response.data);
        this.props.dispatch(loadPosts(response.data));
        this.setState({ hasMoreItems: this.state.posts.length < numberOfPosts ? false : true, page: this.state.page + 1 });
      })
      .catch(error => console.log(error));
  }

  render() {
    let items = [];
    this.state.posts.map((post, index) => {
      items.push(
        < ... key={index}>
          ...
        </...>
      );
    });

    return (
      <InfiniteScroll
        pageStart={0}
        loadMore={this.loadMore}
        hasMore={this.state.hasMoreItems}
        loader={<p>Loading...</p>}>
          { items }
      </InfiniteScroll>
    );
  }
}

const mapStateToProps = (state) => {
  return {
    timestamp: state.timestampReducer,
    posts: state.postsReducer
  }
};

export default connect(mapStateToProps)(Feed);

Я использовал избыточность для управления состоянием своих сообщений.Затем я добавил gem 'kaminari' в свой gem-файл и запустил bundle installed, затем добавил эту строку в действие индекса моего контроллера: @posts = Post.all.order(created_at: :desc).page params[:page] и это в моей модели: paginates_per 5.

Теперь он прокручивается и загружается какожидается!Потрясающе.

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Решением будет использование нумерации страниц.Каждый запрос будет содержать только набор записей, которые вы укажете в методе.Вы можете выполнять с помощью драгоценных камней, таких как will_paginate , kaminari , и это новый камень под названием pagy , и они утверждают, что он быстрее, чем два других.

Просто увеличивайте параметр страницы в URL после каждого запроса до последней страницы, и вы получите нужный результат.

Я рад, что мое мнение помогло вам:)

Измените свой код JS на это:

axios.post('/posts.json', {
  params: {
    page: page
  }
}).then((response) => {
    console.log(response.data);
    ...
  }).catch(error => console.log(error));
}
0 голосов
/ 08 октября 2018

Посмотрите на console.log (response) после метода axios then, чтобы увидеть массив объектов, возвращаемых с сервера.После этого вы можете установить его с помощью свойства .length метода, например:

axios.get('/posts.json')
  .then((response) => {

    if(response.data.length > 20){
      console.log(response.data.slice(0,20))
      }
  })
  .catch(error => console.log(error));
...