Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用ReactJS在AJAX调用后处理Rails flash消息_Javascript_Ruby On Rails_Ajax_Reactjs - Fatal编程技术网

Javascript 使用ReactJS在AJAX调用后处理Rails flash消息

Javascript 使用ReactJS在AJAX调用后处理Rails flash消息,javascript,ruby-on-rails,ajax,reactjs,Javascript,Ruby On Rails,Ajax,Reactjs,有几篇文章描述了在AJAX调用后显示flash消息(例如,和) 我正在使用并希望这样做,并且希望利用React的动态显示渲染 因此,我在回答我自己的问题,即当使用下面的ReactJS回答其他可能遇到此问题的人并获得改进建议时,如何在AJAX调用后呈现flash消息。此实现主要基于关于此主题的其他So帖子(请参阅相关参考文献)。代码假定Rails4.x带有资产管道,HAML用于视图,引导用于样式设置,以及gem的使用 (更新:稍长的讨论可在上找到) 布局 以下是app/views/layouts/

有几篇文章描述了在AJAX调用后显示flash消息(例如,和)

我正在使用并希望这样做,并且希望利用React的动态显示渲染


因此,我在回答我自己的问题,即当使用下面的ReactJS回答其他可能遇到此问题的人并获得改进建议时,如何在AJAX调用后呈现flash消息。

此实现主要基于关于此主题的其他So帖子(请参阅相关参考文献)。代码假定Rails4.x带有资产管道,HAML用于视图,引导用于样式设置,以及gem的使用

(更新:稍长的讨论可在上找到)

布局
以下是
app/views/layouts/application.html.haml
文件:

!!!
%html
  %head
    %title
      Demo

    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true
    = javascript_include_tag 'application', 'data-turbolinks-track' => true
    = csrf_meta_tags

  %body
    %div.container
      %div#flash_messages
      = yield
请注意,
div
的id为
#flash_messages
。此容器div的位置决定了flash消息的显示位置

控制器
下面的私有例程只是将数组的本机数组转换为头中可解析的JSON

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  after_filter :flash_to_http_header

private
  def flash_to_http_header
    return unless request.xhr?
    return if flash.empty?
    response.headers['X-FlashMessages'] = flash.to_hash.to_json
    flash.discard  # don't want the flash to appear when you reload page
  end
end
FlashMessages
React类做了一些事情。首先,它将道具移动到状态。通常这是一种反模式,但这样做会使非反应代码在需要时触发更改。
messages
函数就是触发器,它意味着由外部JS代码调用。
render
的主处理假定Rails flash原生array-of-2-element-array数据结构将处理量保持在最低限度,并允许从视图直接使用组件,而不仅仅是AJAX调用。最后,local
\u flash\u class
方法支持引导样式(当然可以根据需要调整其他样式)

handleFlashMessagesHeader是一个全局函数,用于将JSON转换回Rails控制器过滤器方法完成的数组。注意,它从Rails应用程序视图/布局中获取带有id标记的DOM元素

最后一部分是在页面加载时运行的,因此取决于jqueryready。
React.render
(正式的
React.renderComponent
)保存到一个全局变量中,以允许直接调用
FlashMessages
对象的
message
方法(使用的
dummy
数组在第一次调用时只是为一个空的flash数组种子——这可能也可以在React类中通过空测试来处理)。每当触发
ajaxComplete
时,就会调用
handleFlashMessageHeader
函数并传递React对象进行更新

非AJAX
因为React类假定数组的本机数组,所以视图可以简单地调用

= react-component 'FlashMessages', flash, :div

而是显示它,但由于不支持动态响应,因此它的用处当然较小。但是,无论哪种方式调用它的能力都为某些用例提供了更大的灵活性。

我无法获得@rdnewman对Rails 5和react Rails 1.9.0(对应于react 15.3.0)的回答.我认为React中发生了一些变化,不允许外部访问函数,因此在
handleFlashMessagesHeader()
中调用
.messages()
无法工作(未找到函数)

我将答案改编为适合我的答案。我只是在学习如何反应,所以可能有更好的方法,但我得到的是:

app/controllers/application\u controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  after_action :flash_to_http_header, if: -> { request.xhr? }

  private

  def flash_to_http_header
    return if flash.empty?
    response.headers['X-FlashMessages'] = flash.to_hash.to_json
    flash.discard
  end
end
app/views/layouts/application.html.erb

<%= react_component 'FlashMessages', { data: flash.to_hash } %>

这将在页面加载时呈现标准flash消息,并在任何Ajax请求后更新/替换它们。如果您使用
react rails
gem,您只需将文件放入
components
目录,一切都应该正常

@FlashMessages = React.createClass
  getInitialState: ->
    messages: @props.data
  getDefaultProps: ->
    messages: {}
  componentDidMount: ->
    $(document).ajaxComplete ((event, xhr, settings) ->
      header_messages = xhr.getResponseHeader('X-FlashMessages')
      messages = {}
      if header_messages
        messages = JSON.parse(header_messages)
      @replaceState {messages: messages}
    ).bind(this)
  messageClass: (messageType) ->
    if messageType == 'notice'
      return 'alert alert-warning'
    if messageType == 'success'
      return 'alert alert-success'
    return 'alert alert-error'
  render: ->
    React.DOM.div
      className: 'flash-messages'
      for messageType of @state.messages
        React.DOM.div
          className: @messageClass(messageType)
          key: messageType
          @state.messages[messageType]
<%= react_component 'FlashMessages', { data: flash.to_hash } %>