Я пытаюсь использовать ActionCable и веб-сокеты для реализации страницы, где сервер выполняет какие-то действия через задание Sidekiq и отправляет сообщения обратно в браузер пользователя, чтобы обновить страницу. Должно быть просто, верно?
Я делаю первую основную вещь c, которая по сути отправляет сообщение в контроллере, и браузер Javascript должен его обработать. Ну, это так, но это так хорошо , прежде чем страница будет загружена / готова. И я пытаюсь выяснить, почему.
Вот упрощенный контроллер:
def create
some stuff
render
ActionCable.server.broadcast "opml_items_channel:#{current_user.id}",
{ message: "Current Status: Found #{@opml_items.length} items" }
end
А вот Javascript для канала:
App.opmlitems = App.cable.subscriptions.create("OpmlItemsChannel", {
connected: function() {
//console.log("connected");
},
disconnected: function() {
//console.log("disconnected");
},
received: function(data) {
//console.log("recieved");
console.log(data['message']);
// wait for document ready otherwise the message comes before the
// page is rendered
$( document ).ready(function() {
console.log("doing the thing")
console.log(document.querySelector('#status-p'));
if ( document.querySelector('#status-p') != null ) {
document.querySelector('#status-p').innerText = data['message'];
}
});
}
});
Это полностью работает в том, что консоль регистрирует «что-то» , но делает это даже до полной загрузки страницы браузером, несмотря на document.ready
. Глядя на консоль браузера, я вижу:
Current Status: Found 11 items
doing the thing
null
Navigated to http://localhost:3000/opml_items
null
потому, что #status-p
еще не существует во время вызова функции received
.
В журнале рельсов я вижу:
Started POST "/opml_items" for 127.0.0.1 at 2020-04-06 01:14:33 +0000
Processing by OpmlItemsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7UQye0uFoThYZvoP8cxW/Wbz+QEi6IR5TXYoJFQeD1cXl5h6SZRYDpAyRIX7EYoQu6mGO/r76XgGZRap2le1hQ==", "upload"=>{"opml_file"=>#<ActionDispatch::Http::UploadedFile:0x00007f0bfeeac3b8 @tempfile=#<Tempfile:/tmp/RackMultipart20200406-358-1ekfo8l.opml>, @original_filename="too-many.opml", @content_type="text/x-opml+xml", @headers="Content-Disposition: form-data; name=\"upload[opml_file]\"; filename=\"too-many.opml\"\r\nContent-Type: text/x-opml+xml\r\n">}, "commit"=>"Import OPML"}
blah blah standard rails stuff
[ActionCable] Broadcasting to opml_items_channel:1: {:message=>"Current Status: Found 11 items"}
Completed 200 OK in 713ms (Views: 612.4ms | ActiveRecord: 28.8ms | Elasticsearch: 0.0ms)
Итак, это долгий путь вопроса - как я могу заставить сообщения ActionCable полностью приходить после рендеринга страницы? Вы можете видеть мой render
, который указывает, что порядок ( в журнале ) указывает на то, что сообщение ActionCable приходит в самом конце. Тем не менее, что касается браузера, он все еще, кажется, не соблюдает ready
.
WDYT?