【问题标题】:How to use view_component inside stimulus controller如何在刺激控制器中使用 view_component
【发布时间】:2022-11-18 14:13:54
【问题描述】:

嗨,我是 ROR 的初学者,正在使用 view_components 和 stimulus js 从事非常简单的项目。我有 InputCommentComponent view_component 我想通过刺激控制器在单击某些按钮时将其附加为 div 中的子节点。但是我的组件在刺激控制器内部是未定义的。我怎样才能访问它并附加到 div。

//input_comment_compopnent.html.erb
<%= form_with(model: @comment, local: true,  data: { turbo: false}) do |f| %>
  <div class="mb-4">
    <%= f.text_field :description, :required => true, class: "mb-3 w-2/3 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500", placeholder: "Add Comment ..." %>
    <%= f.hidden_field :post_id, value: @post_id %>
    <%= f.hidden_field :user_id, value: @user_id %>
    <%= f.hidden_field :reply_to, value: @reply_to %>
    <div class='sm:flex sm:flex-row-reverse mb-4 w-2/3'>
      <%= f.submit 'Submit', class: "inline-flex items-center justify-center px-4 py-2 bg-brand-primary font-semibold capitalize text-white hover:bg-brand-primary-hover active:bg-brand-primary disabled:opacity-25 transition" %>
    </div>
  </div>
<% end %>

// input_comment_component.rb
class Input::InputCommentComponent < ViewComponent::Base
  def initialize(comment: nil, post_id: nil, user_id: nil, reply_to: nil)
    @comment = comment
    @post_id = post_id
    @user_id = user_id
    @reply_to = reply_to
  end

end

//comment_controller.js
import {Controller} from '@hotwired/stimulus'

export default class extends Controller {
  static targets = ['wrapper']

  addComment() {
    this.wrapperTarget.appendChild(Input::InputCommentComponent.new)
    // or
    this.wrapperTarget.appendChild(render(Input::InputCommentComponent.new))

  }
}

但是我无法访问控制器内部的组件并收到一些附加的语法错误。

任何帮助或提示将不胜感激。

【问题讨论】:

    标签: ruby-on-rails ruby stimulusjs stimulus-reflex view-components


    【解决方案1】:

    您不能在刺激内渲染视图组件组件,因为该组件需要作为服务器端呈现,而当您使用刺激时,您正在客户端工作。 所以你应该使用 turbo frame (https://turbo.hotwired.dev/) 来异步渲染这个组件。

    • 首先创建一个涡轮帧端点。
    • 之后创建调用此 turbo 端点的请求并附加 html 代码

    【讨论】:

    【解决方案2】:

    在没有任何 JS 的情况下将视图组件附加到任何 Dom 元素的一种非常优雅和简单的方法是使用 stimulus_reflex 广播您的视图组件 cable_ready

    stimulus reflex 允许您在 ruby​​ 中定义一个反射类并在 Dom 元素 ex 上调用它:

    example_reflex.rb

    class ExampleReflex < StimulusReflex::Reflex
    
      def trigger
        cable_ready.append(
          selector: "#targeted-div", 
          html: render(Input::InputCommentComponent.new)).broadcast
        morph :nothing
      end
    end
    

    example_view.html.erb

    <div id="targeted-div" ></div>
    <button data-reflex="click->ExampleReflex#trigger" > click to append View component </button>
    

    【讨论】:

      猜你喜欢
      • 2023-01-01
      • 2021-02-13
      • 2022-06-26
      • 2020-11-11
      • 2021-07-20
      • 2022-06-29
      • 2021-03-06
      • 2022-01-06
      • 2021-11-09
      相关资源
      最近更新 更多