英文:
rails turbo frame apparently updating but browser window remains unaltered
问题
以下是翻译好的部分:
The following `_receipt_number` partial (HTML formatting tags removed for brevity's sake)
is rendered in HTML as:
Via a javascript that controls the device camera a scan is run and is processed (this is the relevant javascript code for the instance)
via the controller action with:
the log shows the action processing, however **without a format pre-defined for the contorller** and rendering required objects:
The turbo_stream.erb response is set as:
and the console advises that the HTML is received over the wire XHRPOSThttp://localhost:3000/carts/6/update_receipt_number with the following payload
Yet the browser window does not update.
I do not believe the controller's absence of request type is at play, as the response arrives to the browser. So why is the browser not refreshing the turbo_frame? *the same was attempted with a div in lieu of the turbo_frame, leading to identical behavior*
What am I missing?
英文:
The following _receipt_number
partial (HTML formatting tags removed for brevity's sake)
<%= turbo_frame_tag :receipt_number do %>
<%= t('scan') %> <%= t('cart.receipt_number') %>
<h3><%= @cart.receipt_number %></h3>
<% if @cart.receipt_number %>
<%= button_to t('change'), clear_receipt_number_cart_path(id: @cart.id), class: 'button warning', method: :patch %>
<% end %>
<% end %>
is rendered in HTML as:
<turbo-frame id="receipt_number">
scan receipt number
<h3></h3>
</turbo-frame>
Via a javascript that controls the device camera a scan is run and is processed (this is the relevant javascript code for the instance)
let formData = new FormData();
let CodeParams = {
code_data: result.text,
id: <%= @cart.id %>
};
formData.append("code_json_data", JSON.stringify(CodeParams));
fetch("update_receipt_number", {
method: "post",
format: "turbo_stream",
body: formData,
headers: {
"X-CSRF-Token": document.querySelector("[name='csrf-token']").content,
}
});
codeReader.reset();
via the controller action with:
@cart.update(receipt_number: result['code_data'])
respond_to do |format|
format.turbo_stream
end
the log shows the action processing, however without a format pre-defined for the contorller and rendering required objects:
Started POST "/carts/6/update_receipt_number" for 127.0.0.1 at 2023-02-27 08:24:38 +0100
Processing by CartsController#update_receipt_number as */*
Cart Update (9.6ms) UPDATE "carts" SET "updated_at" = $1, "receipt_number" = $2 WHERE "carts"."id" = $3
Rendering carts/update_receipt_number.turbo_stream.erb
Rendered carts/_receipt_number.html.erb (Duration: 0.8ms | Allocations: 349)
Rendered carts/update_receipt_number.turbo_stream.erb (Duration: 1.9ms | Allocations: 663)
The turbo_stream.erb response is set as:
<%= turbo_stream.replace :receipt_number do %>
# replacing the partial with turbo
<%= render partial: 'carts/receipt_number', locals: {cart: @cart} %>
<% end %>
and the console advises that the HTML is received over the wire XHRPOSThttp://localhost:3000/carts/6/update_receipt_number
with the following payload
[HTTP/1.1 200 OK 357ms]
<turbo-stream action="replace" target="receipt_number"><template>
# replacing the partial with turbo
<turbo-frame id="receipt_number">
scan receipt number
<h3>20230224T12423036270004131601843bbaa16909b1b07b2c32414fdea5092de2769aabaa2f610860c827f27fb386d4</h3>
<form class="button_to" method="post" action="/carts/6/clear_receipt_number"><input type="hidden" name="_method" value="patch" autocomplete="off" /><button class="button warning" type="submit">change</button><input type="hidden" name="authenticity_token" value="DKVdhPK4UfmY_PzvA2amrvh9IejYEnyjHrJQANs0rlj6HHNAZjk3n6zxAgHRg0s27SWwgPZxMXOuLDiqSn6oQw" autocomplete="off" /></form>
</turbo-frame>
</template></turbo-stream>
Yet the browser window does not update.
I do not believe the controller's absence of request type is at play, as the response arrives to the browser. So why is the browser not refreshing the turbo_frame? the same was attempted with a div in lieu of the turbo_frame, leading to identical behaviour
What am I missing?
答案1
得分: 3
自从您自己发出fetch
请求后,您也必须自己处理响应。换句话说,您已经调用了一个方法,现在必须对返回的值采取一些操作。
通常情况下,turbo会处理繁琐的细节,但幸运的是,它确实提供了手动呈现流的API:
fetch("update_receipt_number", {
method: "post",
// format: "turbo_stream", // <= 我认为这不是一个有效的选项
body: formData,
headers: {
"X-CSRF-Token": document.querySelector("[name='csrf-token']").content,
// 设置 Accept 标头以发出正确的 TURBO_STREAM 请求
"Accept": "text/vnd.turbo-stream.html"
}
})
.then(response => response.text())
.then(text => Turbo.renderStreamMessage(text));
相关链接:
https://turbo.hotwired.dev/reference/streams#processing-stream-elements
https://developer.mozilla.org/en-US/docs/Web/API/Response/text
英文:
Since you're issuing fetch
request yourself, you have to handle the response yourself as well. In other words, you have called a method and now you have to do something with the returned value.
Normally turbo would handle the nitty gritty details, but thankfully, it does expose an api for rendering a stream manually:
fetch("update_receipt_number", {
method: "post",
// format: "turbo_stream", // <= i don't think, this is a thing
body: formData,
headers: {
"X-CSRF-Token": document.querySelector("[name='csrf-token']").content,
// set Accept header to issue a proper TURBO_STREAM request
"Accept": "text/vnd.turbo-stream.html"
}
})
.then(response => response.text())
.then(text => Turbo.renderStreamMessage(text));
https://turbo.hotwired.dev/reference/streams#processing-stream-elements
https://developer.mozilla.org/en-US/docs/Web/API/Response/text
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论