使用 Rails 进行敏捷 Web 开发 5 - Action Cable
Agile Web Development with Rails 5 - Action Cable
我正在研究书中的 ActionCable 示例。所有代码都按照描述添加,我可以看到 ActionCable 服务器日志命中,但更新页面从不更新项目的成本。我错过了什么?
以下日志条目告诉我 ActionCable 正在发射。代码如下。
Product Load (0.1ms) SELECT "products".* FROM "products"
Rendered store/index.html.erb (6.0ms)
[ActionCable] Broadcasting to products: {:html=>"<p id=\"notice\"></p>\n\n<h1>Your Pragmatic Catalog</h1>\n\n\n\n <div class=\"entry\">\n\n <img src=\"/assets/dcbang-28758120ca6616f3f95a4b73dda112a1f8e6ac3175e35b67e78d0ab0bd177566.jpg\" alt=\"Dcbang\" />\n <h3>Rails, Angular, Postgres, and Bootstrap</h3>\n\n <p>\r\n <em>Powerful, Effective, and Efficient Full-Stack Web Development</em>\r\n As a Rails developer, you care about user experience and performance,\r\n but you also want simple and maintainable code. Achieve all that by\r\n embracing the full stack of web development, from styling with\r\n Bootstrap, building an interactive user interface with AngularJS, to\r\n storing data quickly and reliably in PostgreSQL. Take a holistic view of\r\n full-stack development to create usable, high-performing applications,\r\n and learn to use these technologies effectively in a Ruby on Rails\r\n environment.\r\n </p>\n\n <div class=\"price_line\">\n <span class=\"price\">.00</span>\n\n <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=2\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"FCedsTsN/GG6cm0VhcmY7SdGjpRzCKuuSyxKJt/Kak1Xdv/gUFVU1UYXr8n7nm2cKgvjwS23zcBorzf5P5lieg==\" /></form>\n\n </div>\n\n </div>\n\n\n <div class=\"entry\">\n\n <img src=\"/assets/7apps-f67c3d908f537bac34a290206cc1db4c6f4611196c550e49ba836b796a2602bb.jpg\" alt=\"7apps\" />\n <h3>Seven Mobile Apps in Seven Weeks</h3>\n\n <p>\r\n <em>Native Apps, Multiple Platforms</em>\r\n Answer the question “Can we build this for ALL the devices?” with a\r\n resounding YES. This book will help you get there with a real-world\r\n introduction to seven platforms, whether you’re new to mobile or an\r\n experienced developer needing to expand your options. Plus, you’ll find\r\n out which cross-platform solution makes the most sense for your needs.\r\n </p>\n\n <div class=\"price_line\">\n <span class=\"price\">.00</span>\n\n <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=3\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"faFaDWHEcOVsP5x1x8s+A3Zd6fpFbVsW4JZzdDgpNOA+8DhcCpzYUZBaXqm5nMtyexCErxvSPXjDFQ6r2Ho81w==\" /></form>\n\n </div>\n\n </div>\n\n\n <div class=\"entry\">\n\n <img src=\"/assets/adrpo-23a974519e0d4353c6906f82b40bd4cd98b09a2ce748825370c7aa59763f5ac7.jpg\" alt=\"Adrpo\" />\n <h3>Ruby Performance Optimization</h3>\n\n <p>\n <em>Why Ruby Is Slow, and How to Fix It</em>\n You don’t have to accept slow Ruby or Rails performance. In this\n comprehensive guide to Ruby optimization, you’ll learn how to write\n faster Ruby code—but that’s just the beginning. See exactly what makes\n Ruby and Rails code slow, and how to fix it. Alex Dymo will guide you\n through perils of memory and CPU optimization, profiling, measuring,\n performance testing, garbage collection, and tuning. You’ll find that\n all those “hard” things aren’t so difficult after all, and your code\n will run orders of magnitude faster.\n </p>\n\n <div class=\"price_line\">\n <span class=\"price\">.00</span>\n\n <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=4\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"tN4iplT2QTAi9zwvn9ZXkNHwKPJouOcXz+zr0Pnytuz3j0D3P67phN6S/vPhgaLh3L1FpzYHgXnsb5YPGaG+2w==\" /></form>\n\n </div>\n\n </div>\n\n"}
Redirected to http://localhost:3000/products/2
Completed 302 Found in 23ms (ActiveRecord: 1.8ms)
**#assets/javascripts/channels/products.coffee**
App.products = App.cable.subscriptions.create "ProductsChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
# Called when there's incoming data on the websocket for this channel
$(".store #main").html(data.html)
**#app/views/store/index.html.erb**
<p id="notice"><%= notice %></p>
<h1>Your Pragmatic Catalog</h1>
<% cache @products do %>
<% @products.each do |product| %>
<% cache product do %>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%= product.title %></h3>
<%= sanitize(product.description) %>
<div class="price_line">
<span class="price"><%= number_to_currency(product.price) %></span>
<%= button_to 'Add to Cart', line_items_path(product_id: product.id), remote:true %>
</div>
</div>
<% end %>
<% end %>
<% end %>
#app/channels/products_channel.rb
class ProductsChannel < ApplicationCable::Channel
def subscribed
# stream_from "some_channel"
stream_from "products"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
#application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= csrf_meta_tags %>
</head>
<body class='<%= controller.controller_name %>'>
<div id="banner">
<%= image_tag 'logo.svg', alt: 'The Pragmatic Bookshelf' %>
<span class="title"><%= @page_title %></span>
</div>
<div id="columns">
<div id="side">
<div id="cart">
<% if @cart %>
<%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %>
<%= render @cart %>
<% end %>
<% end %>
</div>
<ul>
<li><a href="http://www...">Home</a></li>
<li><a href="http://www.../faq">Questions</a></li>
<li><a href="http://www.../news">News</a></li>
<li><a href="http://www.../contact">Contact</a></li>
</ul>
</div>
<div id="main">
<%= yield %>
</div>
</div>
</body>
</html>
在您的 received
函数中,您试图访问一个似乎不存在的元素 (.store #main
),因为您没有带有 class 的元素store
在您发布的代码上。
尝试将代码更改为:
received: (data) ->
$("#main").html(data.html)
因为页面上存在 #main
元素。
我正在研究书中的 ActionCable 示例。所有代码都按照描述添加,我可以看到 ActionCable 服务器日志命中,但更新页面从不更新项目的成本。我错过了什么?
以下日志条目告诉我 ActionCable 正在发射。代码如下。
Product Load (0.1ms) SELECT "products".* FROM "products"
Rendered store/index.html.erb (6.0ms)
[ActionCable] Broadcasting to products: {:html=>"<p id=\"notice\"></p>\n\n<h1>Your Pragmatic Catalog</h1>\n\n\n\n <div class=\"entry\">\n\n <img src=\"/assets/dcbang-28758120ca6616f3f95a4b73dda112a1f8e6ac3175e35b67e78d0ab0bd177566.jpg\" alt=\"Dcbang\" />\n <h3>Rails, Angular, Postgres, and Bootstrap</h3>\n\n <p>\r\n <em>Powerful, Effective, and Efficient Full-Stack Web Development</em>\r\n As a Rails developer, you care about user experience and performance,\r\n but you also want simple and maintainable code. Achieve all that by\r\n embracing the full stack of web development, from styling with\r\n Bootstrap, building an interactive user interface with AngularJS, to\r\n storing data quickly and reliably in PostgreSQL. Take a holistic view of\r\n full-stack development to create usable, high-performing applications,\r\n and learn to use these technologies effectively in a Ruby on Rails\r\n environment.\r\n </p>\n\n <div class=\"price_line\">\n <span class=\"price\">.00</span>\n\n <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=2\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"FCedsTsN/GG6cm0VhcmY7SdGjpRzCKuuSyxKJt/Kak1Xdv/gUFVU1UYXr8n7nm2cKgvjwS23zcBorzf5P5lieg==\" /></form>\n\n </div>\n\n </div>\n\n\n <div class=\"entry\">\n\n <img src=\"/assets/7apps-f67c3d908f537bac34a290206cc1db4c6f4611196c550e49ba836b796a2602bb.jpg\" alt=\"7apps\" />\n <h3>Seven Mobile Apps in Seven Weeks</h3>\n\n <p>\r\n <em>Native Apps, Multiple Platforms</em>\r\n Answer the question “Can we build this for ALL the devices?” with a\r\n resounding YES. This book will help you get there with a real-world\r\n introduction to seven platforms, whether you’re new to mobile or an\r\n experienced developer needing to expand your options. Plus, you’ll find\r\n out which cross-platform solution makes the most sense for your needs.\r\n </p>\n\n <div class=\"price_line\">\n <span class=\"price\">.00</span>\n\n <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=3\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"faFaDWHEcOVsP5x1x8s+A3Zd6fpFbVsW4JZzdDgpNOA+8DhcCpzYUZBaXqm5nMtyexCErxvSPXjDFQ6r2Ho81w==\" /></form>\n\n </div>\n\n </div>\n\n\n <div class=\"entry\">\n\n <img src=\"/assets/adrpo-23a974519e0d4353c6906f82b40bd4cd98b09a2ce748825370c7aa59763f5ac7.jpg\" alt=\"Adrpo\" />\n <h3>Ruby Performance Optimization</h3>\n\n <p>\n <em>Why Ruby Is Slow, and How to Fix It</em>\n You don’t have to accept slow Ruby or Rails performance. In this\n comprehensive guide to Ruby optimization, you’ll learn how to write\n faster Ruby code—but that’s just the beginning. See exactly what makes\n Ruby and Rails code slow, and how to fix it. Alex Dymo will guide you\n through perils of memory and CPU optimization, profiling, measuring,\n performance testing, garbage collection, and tuning. You’ll find that\n all those “hard” things aren’t so difficult after all, and your code\n will run orders of magnitude faster.\n </p>\n\n <div class=\"price_line\">\n <span class=\"price\">.00</span>\n\n <form class=\"button_to\" method=\"post\" action=\"/line_items?product_id=4\" data-remote=\"true\"><input type=\"submit\" value=\"Add to Cart\" /><input type=\"hidden\" name=\"authenticity_token\" value=\"tN4iplT2QTAi9zwvn9ZXkNHwKPJouOcXz+zr0Pnytuz3j0D3P67phN6S/vPhgaLh3L1FpzYHgXnsb5YPGaG+2w==\" /></form>\n\n </div>\n\n </div>\n\n"}
Redirected to http://localhost:3000/products/2
Completed 302 Found in 23ms (ActiveRecord: 1.8ms)
**#assets/javascripts/channels/products.coffee**
App.products = App.cable.subscriptions.create "ProductsChannel",
connected: ->
# Called when the subscription is ready for use on the server
disconnected: ->
# Called when the subscription has been terminated by the server
received: (data) ->
# Called when there's incoming data on the websocket for this channel
$(".store #main").html(data.html)
**#app/views/store/index.html.erb**
<p id="notice"><%= notice %></p>
<h1>Your Pragmatic Catalog</h1>
<% cache @products do %>
<% @products.each do |product| %>
<% cache product do %>
<div class="entry">
<%= image_tag(product.image_url) %>
<h3><%= product.title %></h3>
<%= sanitize(product.description) %>
<div class="price_line">
<span class="price"><%= number_to_currency(product.price) %></span>
<%= button_to 'Add to Cart', line_items_path(product_id: product.id), remote:true %>
</div>
</div>
<% end %>
<% end %>
<% end %>
#app/channels/products_channel.rb
class ProductsChannel < ApplicationCable::Channel
def subscribed
# stream_from "some_channel"
stream_from "products"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
#application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>Pragprog Books Online Store</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= csrf_meta_tags %>
</head>
<body class='<%= controller.controller_name %>'>
<div id="banner">
<%= image_tag 'logo.svg', alt: 'The Pragmatic Bookshelf' %>
<span class="title"><%= @page_title %></span>
</div>
<div id="columns">
<div id="side">
<div id="cart">
<% if @cart %>
<%= hidden_div_if(@cart.line_items.empty?, id: 'cart') do %>
<%= render @cart %>
<% end %>
<% end %>
</div>
<ul>
<li><a href="http://www...">Home</a></li>
<li><a href="http://www.../faq">Questions</a></li>
<li><a href="http://www.../news">News</a></li>
<li><a href="http://www.../contact">Contact</a></li>
</ul>
</div>
<div id="main">
<%= yield %>
</div>
</div>
</body>
</html>
在您的 received
函数中,您试图访问一个似乎不存在的元素 (.store #main
),因为您没有带有 class 的元素store
在您发布的代码上。
尝试将代码更改为:
received: (data) ->
$("#main").html(data.html)
因为页面上存在 #main
元素。