MAKE SIMPLE RAILS APP WITH ANGULARJS – PART I
Bài đăng này đã không được cập nhật trong 9 năm
I.INTRODUCE ABOUT ANGULARJS
Nếu bạn là developer đã từng quen làm việc với Ruby on Rails hoặc 1 số web framework tương tự khác đều sẽ dễ dàng nhận thấy điểm chung trong thiết kế của chúng đó là sau mỗi tác vụ update hay delete ở server mọi thứ đều sẽ được redirect lại hay nói cách khác page ở client bạn đang tương tác sẽ được reload lại để lấy về các bản ghi mới. Điều đó đôi khi là không cần thiết và lãng phí tài nguyên khi bạn chỉ thay đổi 1 record nhưng phải load lại đến cả nghìn record trong database chưa kể đến layout, css, ...Ở 1 số page cần thiết, chúng ta có thể dễ dàng thay đổi điều đó bằng cách sử dụng các Ajax request, nhưng một cách đồng bộ và hệ thống hơn, AngularJs sinh ra để làm việc đó giúp bạn với live-edit, live-update.
Tận dụng một cách triệt để lợi ích mà AngularJS đem lại, developer có thể tách riêng rẽ client-side và server-side của web app và tiến hành phát triển cả 2 thứ đó song song với nhau cũng như là sử dụng lại 1 cách hiệu quả.Sau đây là một số điểm mạnh của AngularJS:
-
Two Way Data-Binding Bạn có thể thao tác với model ở bất cứ đâu trong application nhờ vào data-binding và cũng không cần phải lo lắng về traversing hay event handler, giờ đây DOM luôn luôn được up-to-date với sự thay đổi trên database hay form input sau khi đã binding với nhau.
-
Templates Nếu đã từng làm việc với thư viện Handlerbars chắc bạn sẽ không còn xa lạ gì với tính năng này, thay vì việc code HTML truyền thống, AngularJS cho phép xây dựng cấu trúc để model được hiển thị ra trên view. Điều đó có nghĩa input của AngularJS sẽ là các DOM thay vì string value của model.HTML template có thể được lưu vào variable và sử dụng lại nhiều lần.
-
MVC AngularJS cũng được thiết kế theo mô hình MVC với đầy đủ 3 thành phần:
-
ViewModel($scope): 1 object chứa thông tin của các records và đôi khi là các method sẽ tương tác với 1 view cụ thể nào đó, ví dụ như $scope sẽ có thể là User.all trong view users/index
-
View: Sử dụng tính năng template và config $routeProvider, AngularJS thậm chí có thể thay thể sever trong việc điều hướng các request và sử dụng view HTML của riêng mình.
-
Controller: chịu trách nhiệm khởi tạo ViewModel và khai báo các method sẽ tương tác với server-side
II.DEMO
Hãy cùng làm thử 1 sample app nho nhỏ để xem AngularJs đem lại những lợi thế gì so với 1 Rails app truyền thống
- Khởi tạo 1 rails app đơn giản:
$rails new task_angular
$cd task_angular
- Tạo 1 model có tên là Task gồm các trường cơ bản:
rails g model task title:string content:string
- Tạo database và migrate:
$rake db:create
$rake db:migrate
-
Tư tưởng chủ đạo của AngularJS chính là server-side đóng vai trò như là 1 api server.
config/routes.rb
Rails.application.routes.draw do
namespace :api, defaults: {format: :json} do //set format mặc định của các request là `json`
namespace :v1 do
resources :tasks
end
end
root to: "home#index" // controller đơn giản để hiển thị homepage
end
- Trong tasks_controller.rb khai báo các action restful cơ bản nhưng chỉ trả ra json status
module Api
module V1
class TasksController < ApplicationController
skip_before_filter :verify_authenticity_token
before_filter :find_model, except: [:index, :create]
respond_to :json
def index
respond_with Task.all
end
def create
@task = Task.new task_params
if @task.save
respond_to do |format|
format.json{render json: @task}
end
end
end
def show
respond_with @task
end
def update
if @task.update task_params
respond_to do |format|
format.json{render json: @task}
end
end
end
def destroy
respond_with Task.destroy params[:id]
end
private
def find_model
@task = Task.find(params[:id]) if params[:id]
end
def task_params
params.permit :title, :content
end
end
end
end
- Khởi tạo angular trong
app/assets/javascripts/main.js
angular.module('demoApp', ['ngResource']);
- Khởi tạo 2 method là
create
vàdelete
trongapp/assets/javascripts/angular/controlers/tasks.js
đường dẫn mặc định sẽ được dẫn đến/api/v1/tasks/taskId
và model sẽ là Task
angular.module('demoApp').factory('Task', function($resource){
return $resource('/api/v1/tasks/:taskId');
});
angular.module('demoApp').controller('TasksCtrl', function($scope, Task){
$scope.tasks = Task.query();
$scope.create = function(title, content){
Task.save({title: title, content: content}, function(task) {
$scope.tasks.push(task);
});
};
$scope.delete = function(index) {
Task.delete({taskId:$scope.tasks[index].id}, function() {
$scope.tasks.splice(index, 1);
});
};
});
- Khởi tạo
app/views/layouts/application.html.erb
<!DOCTYPE html>
<html class="no-js" ng-app="demoApp"><!--khai báo thẻ html thuộc quyền xử lí của demoApp-->
<head>
<meta charset="utf-8">
<title>TaskAngular</title>
<script src="https://code.jquery.com/jquery-2.1.1.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" >
<%= yield %>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular-resource.min.js"></script>
<%= javascript_include_tag 'application'%>
</div>
</body>
</html>
app/views/home/index.html.haml
<div class="row" ng-controller="TasksCtrl">
<div class="span5">
<form ng-submit="create(title, body)" class='well'>
<h3>Tasks</h3>
<fieldset>
<input ng-model='title' type="text" class="input-xlarge" placeholder="Title..." required>
<br/>
<textarea rows='10' ng-model="content" type="text" class="input-xlarge" placeholder="Text..." required></textarea>
<br/>
<button type="submit" class="btn">Submit</button>
</fieldset>
</form>
</div>
<div class="span5 offset2">
<div class="well" ng-repeat="task in tasks">
<a href="" title="Delete" ng-click="delete($index)" class="pull-right">Delete</a>
<h3>{{task.title}}</h3>
<p>{{task.content}}</p>
</div>
</div>
<div>
-
Chạy
localhost:3000
và cùng xem thành quả. Bây giờ chúng ta có thể tạo ra 1 task mới, được tự động thêm vào list hay xóa đi mà không cần phải reload lại trang web.Các bạn có thể tham khảo source code cho part I tại đây
All rights reserved