Using CoffeeScript in Rails
Bài đăng này đã không được cập nhật trong 9 năm
I. Lời mở đầu
Ngôn ngữ lập trình CoffeeScript
được xây dựng dựa trên JavaScript
, nó biên dịch thành JS rõ ràng, hiệu quả để có thể chạy trên một trình duyệt web hoặc sử dụng với các công nghệ như Node.js
cho các ứng dụng máy chủ.
CoffeScript giải quyết các điểm yếu của JS:
- Cung cấp một cú pháp đơn giản hơn, làm giảm sự dập khuôn, chẳng hạn như các dấu ngoặc đơn và các dấu phẩy.
- Sử dụng khoảng trắng như là một cách để tổ chức các đoạn mã.
- Cung cấp cú pháp đơn giản để biểu diễn các hàm.
- Cung cấp sự thừa kế dựa trên lớp.
Cài đặt:
Cho Ubuntu:
- Để cài đặt
CoffeeScript
thì trước tiên cài đặtNodejs
vànpm
:
sudo apt-get install nodejs
sudo apt-get install npm
- Cài đặt CoffeeScript:
npm install -g coffeescript
Sử dụng:
Sau khi cài đặt CoffeeScript, để biên dịch một file mã nguồn CoffeeScript (.coffee
) ta dùng lệnh coffee -c <tên file coffee>
, sau khi biên dịch ta sẽ được một một file JavaScript (.js
) và có thể dùng trực tiếp file này để chạy. Một số lệnh biên dịch khác có thể tham khảo tại (http://coffeescript.org/).
II. Getting Started
- Nếu phiên bản Ruby của bạn là 1.8.7 hoặc cũ hơn thì bạn cần thêm
JSON gem
vào trongGemfile
:
gem "json"
- Cần tới một trình biên dịch để biên dịch CoffeeScript. Nếu sử dụng hệ điều hành
OS-X
,Ruby wrapper
(có trong "coffee-script" gem) sẽ sử dụng trình biên dịch được built trong hệ thống nhưng nếu sử dụng nền tảng khác thì cần nhúngv8
vào trong application bằng cách thêm dòng lệnh sau vào trongGemfile
:
gem 'therubyracer', :require => nil
- Tiếp theo
bundle install
để update gems:
bundle install
III. Writing Some Code
- Đầu tiên cần xóa file JavaScript đã tồn tại và thay thế bằng
jQuery
bằng cách thêm dòng sau vào Gemfile:
gem "coffee-rails", "~> 4.0.0"
gem "jquery-rails"
Sau đó chạy lệnh :
bundle install
rails g jquery:install
- Các đoạn lệnh js (định nghĩa các hàm, các
event
... ) được chứa trong các file có đuôi là.js.coffee
trong thư mụcapp/assets/javascripts
- Trong
application.js
, có 2 cách gọi file.js.coffee
đó :
Cách 1 :
Gọi file đó 1 lần trong application.js
, những file nằm trực tiếp trong thư mục javascripts
thì chỉ cần thêm dòng lệnh sau để load hết các file js cho tất cả các file trong app :
//= require_tree .
Nếu muốn load tất cả các file của 1 folder nào đó trong folder javascripts : ví dụ có folder app/assets/javascripts/home
thì ta sẽ thêm dòng lệnh sau vào application.js
:
//= require_tree ./home
Nếu muốn load riêng 1 file trong 1 folder thì dẫn trực tiếp tới file đó :
//= require_tree ./home/xyz
Trong file application.html.erb
thêm dòng sau để nó load application.js
:
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
Cách 2:
Đưa trực tiếp file js (example.js.coffee
) cần vào trong view (form)
muốn áp dụng , thêm dòng sau vào trong file html
muốn áp dụng:
<%= javascript_include_tag "example" %>
Nếu không muốn viết javascript trong file .js.coffee
thì có thể viết trực tiếp đoạn mã js
đó vào trong file html
. Giả sử có:
1 `button` - `id="side_arc_cat_list_body_disp_img"`
1 `div` - `class="side_arc_cat_list_body"`
Đoạn js sau xử lý event
: khi click button có id="side_arc_cat_list_body_disp_img"
thì sẽ toggleContents
(đẩy ra / thu vào) thẻ div
có class="side_arc_cat_list_body"
:
<%= javascript_tag do %>
$("#side_arc_cat_list_body_disp_img").click(function() {
toggleContents("side_arc_cat_list_body");
});
<% end %>
// $ : sử dụng khi bắt đầu mỗi 1 sự kiện.
toggleContents
là 1 hàm được định nghĩa từ trước trong 1 file .js.coffee
nào đó :
@toggleContents = (strID) ->
objT = $("##{strID}_disp_img")
if objT.attr("class") != ""
$("##{strID}").toggle()
if $("##{strID}").is(":visible")
$.cookie "co_#{strID}", "open"
objT.removeClass "common_icon_window"
objT.addClass "common_icon_minus"
objT.attr "title", I18n.t("js.nanoty_core.home.index.scale_down")
else
$.cookie "co_#{strID}", "close"
objT.removeClass "common_icon_minus"
objT.addClass "common_icon_window"
objT.attr "title", I18n.t("js.nanoty_core.home.index.scale_up")
- 1 lưu ý khi dùng
id
vàclass
chojs
:
id
là duy nhất thường được dùng cho đối tượng đi tác động (event
)
class
thường được gán cho nhiều đối tượng có chung 1 thuôc tính (chung css), thường là đối tượng bị tác động trong event.
id và class được phân biệt với nhau bởi dấu "#" cho id và "." cho class
IV. 1 số lưu ý trong khi sử dụng js :
- Ví dụ nếu muốn
toggleContent
cho cùng 1 div trong nhiều trường hợp (nhiều id cho 1 class="side_diary_comment_write_body") (nhiều tab với nhiều id khác nhau). Nếu viết theo cách đơn thuần :
$("#side_diary_comment_write_body_disp_img").click ->
toggleContents "side_diary_comment_write_body"
$("#side_diary_comment_write_body2_disp_img").click ->
toggleContents "side_diary_comment_write_body"
$("#side_diary_comment_write_body3_disp_img").click ->
toggleContents "side_diary_comment_write_body"
thì vẫn phóng to / thu nhỏ được div, nhưng toggleContent có 1 đặc điểm là khi event đươc thực hiện thì ảnh trên div có id tương ứng sẽ đổi từ common_icon_minus
sang common_icon_window
và ngược lại (được định nghĩa trong hàm toggleContents
). Nếu 1 id cho 1 class --> ok, nhưng trong trường hợp này thì ảnh chỉ đổi đối với tab đầu tiên. Các tab sau nó sẽ tự động thêm index vào sau mỗi tên class của div đó và vì tên class của div không còn nguyên bản nên ko đổi được ảnh.
--> Giải pháp :
Bước 1 : Viết hàm toggleContents
như sau :
toggleContents = (strID) ->
$objT = $("##{strID}_disp_img")
unless $objT.attr("class") == ""
/* modified : ý nghĩa : cắt bỏ hết các đuôi của id để nó trở về id gốc (1,2,3......)
$("#" + strID.replace(/[0-9]/g, '')).toggle() /* modified */
switch $objT.attr("class")
when "common_icon_window"
$objT.removeClass "common_icon_window"
$objT.addClass "common_icon_minus"
$objT.attr "title", I18n.t("js.nanoty_core.home.index.scale_down")
when "common_icon_minus"
$objT.removeClass "common_icon_minus"
$objT.addClass "common_icon_window"
$objT.attr "title", I18n.t("js.nanoty_core.home.index.scale_up")
setContentsCookie strID, $("#" + strID).is(":visible")
Bước 2 : Viết function gọi hàm toogle
/* ứng với div của 2 tab sau (gọi id giả của khối div cần toggle - thêm index vào cho khác với id gốc), ví dụ : "side_diary_comment_write_body2" */
$("#side_diary_comment_write_body_disp_img").click ->
toggleContents "side_diary_comment_write_body"
$("#side_diary_comment_write_body2_disp_img").click ->
toggleContents "side_diary_comment_write_body2"
$("#side_diary_comment_write_body3_disp_img").click ->
toggleContents "side_diary_comment_write_body3"
- Muốn bắt sự kiện khi click 1 đối tượng nào đó nó sẽ redirect về trang trước đó thì viết đoạn js sau :
$ ->
$("#cancel").click ->
window.history.back()
V. Lời kết
-
Ngoài những ví dụ nêu trên thì js còn có rất nhiều ứng dụng hay cho web: kéo thả (
dragdrop
), ẩn hiện form, re-edit, định thời gian xuất hiện của 1 đối tượng ... -
Trang web hữu ích cho việc biên dịch từ js thuần sang js coffee :
- Nguồn tham khảo hữu ích cho việc học js :
https://www.honeybadger.io/blog/2013/12/11/beginners-guide-to-angular-js-rails
http://excid3.com/blog/using-coffeescript-for-rails-views/ http://coffeescript.org/
All rights reserved