+2

ReactJs với Ruby on Rails 5 (Phần 2)

Index, search with ReactJs

Bây giờ mình tạo 1 model event

# db/migrate/20170825065530_create_events.rb
class CreateEvents < ActiveRecord::Migration[5.0]
  def change
    create_table :events do |t|
      t.string :name
      t.date :event_date
      t.text :description
      t.string :place

      t.timestamps
    end
  end
end

Khởi tạo dữ liệu rake db:seed

# db/migrate/seeds.rb
1.upto(10) do |i|
  Event.create(name: "Event #{i}",
               description: "It's sample event witn number #{i}",
               event_date: Date.today + rand(3).months,
               place: "Random place number #{i}")
end

Routes

# config/routes.rb
Rails.application.routes.draw do
  resources :events
  root "homes#index"

  namespace :api do
    namespace :v1 do
      resources :events do
        get :search, on: :collection
      end
    end
  end
end

controllers

# controllers/api/v1/events_controller.rb
class Api::V1::EventsController < ApplicationController
  def index
    render json: Event.all
  end

  def search
    query = params[:query]
    events = Event.where('name LIKE ? OR place LIKE ? OR description LIKE ?',
      "%#{query}%", "%#{query}%", "%#{query}%")
    render json: events
  end
end

views

<!-- views/events/index.html.erb -->
<%= react_component "EventApplication" %>

components

// assets/javascripts/components/event_application.jsx
class EventApplication extends React.Component {
  constructor() {
    super();
    this.state = {events: []}
  }

  componentDidMount() {
    this.getDataFromApi();
  }

  getDataFromApi() {
    var self = this;
    $.ajax({
      url: '/api/v1/events',
      success: function(data) {
        self.setState({ events: data });
      },
      error: function(xhr, status, error) {
        alert('Cannot get data from API: ', error);
      }
    });
  }

  handleSearch(events) {
    this.setState({ events: events });
  }

  handleAdd(event) {
    var events = this.state.events;
    events.push(event);
    this.setState({ events: events });
  }

  render() {
    return(
      <div className="container">
        <div className="jumbotron">
          <h1>ReactJS Tutorial</h1>
        </div>
        <div className="row">
          <div className="col-md-4">
          <SearchForm onSearchChange={this.handleSearch.bind(this)}/>
          </div>
        </div>
        <div className="row">
          <div className="col-md-12">
            <EventTable events={this.state.events} />
          </div>
        </div>
      </div>
    )
  }
}
// assets/javascripts/components/event_table.jsx
class EventTable extends React.Component {
  constructor() {
    super();
  }

  handleSearch(events) {
    this.setState()
  }
  render() {
    var events = [];
    this.props.events.forEach(function(event) {
      events.push(<Event event={event} key={'event' + event.id}/>);
    }.bind(this));
    return(
      <table className="table table-striped">
        <thead>
          <tr>
            <th className="col-md-3">Name</th>
            <th className="col-md-2">Date</th>
            <th className="col-md-3">Place</th>
            <th className="col-md-4">Description</th>
          </tr>
        </thead>
        <tbody>
          {events}
        </tbody>
      </table>
    )
  }
}
// assets/javascripts/components/event.jsx
class Event extends React.Component {
  constructor() {
    super();
  }

  propTypes: {
    name: React.PropTypes.string,
    event_date: React.PropTypes.string,
    place: React.PropTypes.string,
    description: React.PropTypes.string
  }

  render() {
    var event = this.props.event;
    return(
      <tr>
        <td>{event.name}</td>
        <td>{event.event_date}</td>
        <td>{event.place}</td>
        <td>{event.description}</td>
      </tr>
    )
  }
}
// assets/javascripts/components/search_form.jsx
class SearchForm extends React.Component {
  constructor() {
    super();
  }

  handleSearch() {
    var query = $("#query").val();
    var self = this;
    $.ajax({
      url: '/api/v1/events/search',
      data: { query: query },
      success: function(data) {
        self.props.onSearchChange(data)
      },
      error: function(xhr, status, error) {
        alert('Search error: ', status, xhr, error);
      }
    });
  }

  render() {
    return(
      <input onChange={this.handleSearch.bind(this)}
        type="text" className="form-control"
        placeholder="Type search phrase here..." id="query" />
    )
  }
}

Kết quả

Mình đã hướng dẫn xong phần này (mới tìm hiểu nên mình xử lý cở bản)

Link tham khảo: https://www.nopio.com/blog/react-rails-part-1-tutorial/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí