首页 > 解决方案 > 如何从 Rails 视图文件中打开 React Bootstrap 模式

问题描述

我会尽力解释我的困惑点。

在我们的index.html.erb文件中,我们有文本“登录”,旨在链接以触发打开一个简单的模态表单。现在,我想做的只是打开模态。我有以下链接代码,我怀疑它一开始可能是错误的。

<%= link_to 'Login', login_path, {:remote => true, 'data-toggle' => "modal", 'data-target' => '#modal-window'} %>

我在处理远程模式吗?我不知道。/login无论如何,当我将鼠标悬停在链接上时,我可以看到端点,我确实相信这与我在routes.rb文件中定义的路线成功交互,但在多大程度上,我不知道。

get '/login', to: 'sessions#new', as: 'login'

请记住,我之所以能走到这一步,是因为我们有另一个应用程序,它有一个我一直提到的登录页面(不是模式)。所以接下来我想到的是创建以下文件:

app/views/sessions/new.html.erb
app/javascript/packs/sessions/new.js
app/controllers/sessions_controller.rb

sessions_controller.rb文件中,我只定义了新操作,没有别的:

class SessionsController < ApplicationController
  def new
  end
end

从这一点开始,我真的开始不知所措和困惑。我的感觉是该new.html.erb文件应该以某种方式调用 React 代码?因为这是我看到的其他应用程序登录功能的完成方式,所以即使我知道这是错误的,这就是我所拥有的 - 但为什么呢?我错过了什么?

<% content_for :page_title do %>Login<% end %>
<% content_for :container_class do %>sessions-container<% end %>

new.js我有以下用于 Bootstrap 的代码(它包含在我们应用程序的其他地方)模式(我什至没有导入react-bootstrap模块或遵循 ReactModal 语法,因为这会导致一系列全新的问题和混乱):

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios'

export default class SessionsNew extends React.Component {
  constructor (props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div className="container">
        <div className="modal" tabIndex="-1" role="dialog">
          <div className="modal-dialog" role="document">
            <div className="modal-content">
              <div className="modal-header">
                <h5 className="modal-title">Modal title</h5>
                <button type="button" className="close" data-dismiss="modal" aria-label="Close">
                  <span aria-hidden="true">&times;</span>
                </button>
              </div>
              <div className="modal-body">
                <p>Modal body text goes here.</p>
              </div>
              <div className="modal-footer">
                <button type="button" className="btn btn-primary">Save changes</button>
                <button type="button" className="btn btn-secondary" data-dismiss="modal">Close</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

最后,我将SessionsNew组件添加到与我们的文件处于同一级别的另一个 JS 文件中application.js,尽管我不完全理解为什么:

import React, { Component } from 'react'
import ReactDOM from 'react-dom';
import ProductsShow from './products/show'
import SessionsNew from './sessions/new'

const components = {
  'products/show':    { component: <ProductsShow /> },
  'sessions/new':     { component: <SessionsNew /> }
}

if (gon.page_data_controller && gon.page_data_action) {
  const componentKey = gon.page_data_controller + "/" + gon.page_data_action
  if (components[componentKey]) {
    document.addEventListener('DOMContentLoaded', () => {
      ReactDOM.render(components[componentKey].component, document.getElementById('content-container'));
    })
  }
}

我很抱歉,因为我知道这不是一个直截了当的问题,而是更多的呼救声,以便澄清我刚刚分享的任何内容。简而言之,这里有一些我想知道的事情:

我到底要路由到什么地方?事件的流程是什么,即到登录路径的链接路由,然后呢?new.html.erb与文件相比,文件的目的是什么new.js?我是否正确理解我应该为模式的每个方面创建组件 - 从处理状态(打开、关闭等)到处理登录表单交互?

感谢您的阅读,感谢您的帮助,为这篇文章道歉。

标签: ruby-on-railsreactjs

解决方案


解决您的问题的一种方法:

1)为您的登录表单(您的模式)创建一个部分。假设命名为_login.html.erb

2) 在 index.html.erb 文件中的某处添加部分内容

3) 默认情况下,模态应该有一个 display none。

4) 向您的登录链接添加一个 onclick 事件侦听器,以更改模式的显示。例如
link_to 'Login', '#', :onclick => 'displayLoginModal'

,您需要添加一些 javascript 来处理点击事件。此链接可能会有所帮助:https ://www.w3schools.com/howto/howto_css_modals.asp


推荐阅读