Man*_*pez 5 javascript ruby-on-rails stimulusjs turbo-frames
我正在学习 Turbo Frames 和 Streams + Stimulus,所以我可能没有 100% 步入正轨。我有一个用于创建新对象的表单,但在表单中我希望有一个选择组件,该组件将根据选择显示某些字段。值得注意的是,因此,在用户做出此选择之前我不想提交表单。
这就是我所拥有的:
<div class="form-group mb-3">
<%= form.label :parking, class: 'form-label' %>
<%= form.number_field :parking, class: 'form-control' %>
</div>
<%= turbo_frame_tag "turbo_transactions" do %>
<%= render 'property_transactions' %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
<div class="form-group mb-3" data-controller="property-transaction">
<%= label_tag :property_transactions, 'Property in:', class: 'form-label' %>
<%= select_tag :property_transactions, options_for_select(@property_transactions.collect {|p| [p.name, p.id]}), { data:
{ action: "property-transaction#redraw", property_transaction_target: 'transaction', turbo_frame: 'turbo_transactions' },
class: 'form-control', prompt: '', autocomplete: 'off' } %>
</div>
<% if @property_transaction %>
<%= turbo_frame_tag @property_transaction.en_translation_key do %>
<div class="form-group mb-3">
<%= render @property_transaction.en_translation_key %>
</div>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
import { Controller } from "@hotwired/stimulus";
import Rails from "@rails/ujs";
export default class extends Controller {
static targets = [ "transaction" ];
redraw() {
const params = { property_transaction: this.transaction };
Rails.ajax({
type: 'post',
dataType: 'json',
url: "/set_property_transaction",
data: new URLSearchParams(params).toString(),
success: (response) => { console.log('response', response) }
});
}
get transaction() {
return this.transactionTarget.value;
}
}
Run Code Online (Sandbox Code Playgroud)
def set_property_transaction
respond_to do |format|
format.json
format.turbo_stream do
if @property_transactions
@property_transaction = @property_transactions.select { |p| p.id == property_transaction_params }
else
@property_transaction = PropertyTransaction.find(property_transaction_params)
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
<%= turbo_stream.replace @property_transaction.en_translation_key %>
Run Code Online (Sandbox Code Playgroud)
<%= turbo_frame_tag "rent" do %>
<!-- some input fields -->
<% end %>
Run Code Online (Sandbox Code Playgroud)
<%= turbo_frame_tag "rent-with-option-to-buy" do %>
<!-- other input fields -->
<% end %>
Run Code Online (Sandbox Code Playgroud)
<%= turbo_frame_tag "sale" do %>
<!-- more input fields -->
<% end %>
Run Code Online (Sandbox Code Playgroud)
选择该选项时,出现此错误:
Started POST "/set_property_transaction" for ::1 at 2022-09-07 19:49:03 -0600
Processing by PropertiesController#set_property_transaction as JSON
Parameters: {"property_transaction"=>"2"}
Completed 406 Not Acceptable in 223ms (ActiveRecord: 0.0ms | Allocations: 1879)
ActionController::UnknownFormat (PropertiesController#set_property_transaction is missing a template for this request format and variant.
request.formats: ["application/json", "text/javascript", "*/*"]
request.variant: []):
Run Code Online (Sandbox Code Playgroud)
我对此的理解是我缺少 set_property_translation 模板,但我确实有它。不知道我还能做些什么来让它被识别。
莱斯·南丁吉尔的评论无疑给我指明了正确的方向。我将把需要的更改放在这里。
<div class="form-group mb-3" data-controller="property-transaction">
<%= label_tag :property_transactions, 'Propiedad en:', class: 'form-label' %>
<%= select_tag :property_transactions, options_for_select(@property_transactions.collect {|p| [p.name, p.id]}), { data:
{ action: "property-transaction#redraw", property_transaction_target: 'transaction', turbo_frame: "turbo_transactions" },
class: 'form-control', prompt: '', autocomplete: 'off' } %>
</div>
<%= turbo_frame_tag "dynamic_fields" %>
Run Code Online (Sandbox Code Playgroud)
import { Controller } from "@hotwired/stimulus";
import { post } from "@rails/request.js";
export default class extends Controller {
static targets = [ "transaction" ];
async redraw() {
const params = { property_transaction: this.transaction };
const response = await post("/set_property_transaction", {
body: params,
contentType: 'application/json',
responseKind: 'turbo-stream'
});
if (response.ok) {
console.log('all good', response); // not necessary
}
}
get transaction() {
return this.transactionTarget.value;
}
}
Run Code Online (Sandbox Code Playgroud)
<%= turbo_stream.update "dynamic_fields" do %>
<%= render partial: @property_transaction.en_translation_key %>
<% end %>
Run Code Online (Sandbox Code Playgroud)