【问题标题】:Pagination for rails api and react apirails api和react api的分页
【发布时间】:2019-02-15 20:21:49
【问题描述】:

我正在构建一个网络应用程序。为此,我使用rails 作为backend 的api。还将react 用于frontend。我有一个模型user。我想向网站用户显示所有users 及其详细信息。所以我有大约 10,000 多个用户。所以我不能一次将所有用户发送到前端。我想一次只显示 50 个用户。因此,要查看下 50 个用户,前端将向我发送一个新请求以获取下 50 个用户,依此类推。所以我没有得到正确的路径如何构建它。

现在我正在像这样对所有用户进行攻击,而我的服务器正在挂起。

我的users_controller.rb

 class UsersController < ApplicationController
    def index
      users = User.all
      render_success(:ok, users, meta: { message: 'User sucessfully send' })
    end
 end

简而言之 - 我只想在每个请求中向前端发送有限数量的数据。

【问题讨论】:

    标签: ruby-on-rails reactjs pagination rails-api


    【解决方案1】:

    您可以使用gem 'kaminari' 在rails 中进行分页。
    根据页码获取用户:

    class UsersController < ApplicationController
    def index
      per_page = PAGINATION[:users] # you can define it in app_config.yml  
      users = User.page(params[:page]).per(per_page)
      render json: { user_list: users, per_page: per_page, user_count: users.count, success: true }, status: :ok
    end
    

    结束

    在反应中,您可以使用react-paginate 来呈现分页块。

    您可以在用户索引屏幕中呈现它

        renderPaginateBlock = () => {
        const { user_count, per_page } = this.props;
        if (user_count > per_page) {
          return (
            <div align='center'>
              <ReactPaginate
                previousLabel={"<"} nextLabel={">"} marginPagesDisplayed={2}
                pageRangeDisplayed={5} pageCount={this.props.user_count/this.props.per_page}
                onPageChange={(data) => this.getUserWithPagination(data.selected + 1)}
                containerClassName={"pagination custom"} subContainerClassName={"pages pagination"}
                activeClassName={"active"}
              />
            </div>
          );
        }
        else {
          return null;
        }
      }
    

    这是设置current_page和访问API:

    getUserWithPagination = (activePageNo) => {
        const { fetchUsers } = this.props;
        fetchUsers(activePageNo)
      }
    

    【讨论】:

      【解决方案2】:

      您可以使用limitoffset,这是一个示例,它非常简单,不需要任何库:

      Rails 代码:

      # app/controllers/users_controller.rb
      def users
        users = User.limit(params[:limit]).offset(params[:offset])
        render json: { users: users }
      end
      

      反应代码:

      const PER_PAGE = 50  // How much users to load
      export default class Users extends React.Component {
        constructor(props) {
          super(props)
          this.state = {
            offset: 0,
            limit: PER_PAGE,
            users: []
          }
          this.handlePageClickNext = this.handlePageClickNext.bind(this)
          this.handlePageClickPrev = this.handlePageClickPrev.bind(this)
        }
        loadUsersFromServer() {
          fetch(`/users?limit=${this.state.limit}&offset=${this.state.offset}`)
            .then(response => response.json()).then(response => {
            this.setState({ users: response.users })
          })
        }
        handlePageClickPrev() {
          // Load prev 10 users
          let offset = this.state.offset - PER_PAGE
          if (offset < 0) return 
          this.setState({offset: offset}, () => {
            this.loadUsersFromServer();
          });
        };
        handlePageClickNext() {
          // Load next 10 users
          let offset = this.state.offset + PER_PAGE
          if (offset >= this.state.total) return
      
          this.setState({offset: offset}, () => {
            this.loadUsersFromServer();
          });
        };
        componentDidMount() {
          // Load users on start
          this.loadUsersFromServer();
        }
        render() {
           const users = this.state.users.map((u)=> {
             return <li>{u.id}</li>
           })
      
          return (
           <div>
             <ul>
              {users}
             </ul>
             <button onClick={this.handlePageClickPrev}>Prev</button>
             <button onClick={this.handlePageClickNext}>Next</button>
           </div>
         );
        }
      }
      

      【讨论】:

      • 这种情况下如何设置this.state.total?
      【解决方案3】:

      我不知道这是否可以帮助你。但是你可以使用 will_paginate gem,

      gem 'will_paginate'
      gem 'bootstrap-will_paginate'
      

      在你的索引函数中使用

      @users = User.paginate(page: params[:page], per_page: 50)
      

      使用它,您将在一个请求中发送所有用户并进行分页

      【讨论】:

        猜你喜欢
        • 2019-04-12
        • 2020-06-10
        • 2017-08-24
        • 1970-01-01
        • 2013-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多