Install Angular and Bootstrap in Rails
Bài đăng này đã không được cập nhật trong 3 năm
Bài viết này mình xin giới thiệu về cách cài đặt, sử dụng angular và bootstrap trong rails
Việc đầu tiên bạn phải tạo ra 1 app của rails bằng lệnh
rails new example
Vào thư mục Gemfile liệt kê các gem cần thiết, nhớ bỏ gem turbolinks
ra khỏi Gemfile
gem 'sass', '3.2.19'
group :test, :development do
gem "rspec-rails", "~> 2.0"
gem "factory_girl_rails", "~> 4.0"
gem "capybara"
gem "database_cleaner"
gem "selenium-webdriver"
end
Lưu ý: Bạn phải cài 2 gem capybara và selenium-webdriver này để test và bạn phải cài firefox làm môi trường test
Các câu lệnh sau để cài đặt và chạy chương trình
bundle install
rake db:create
rails s
Front-end phụ thuộc vào quản lý của Bower
Bởi vì rails không cung cấp bất kỳ cách quản lý font-end asset nào. Không giống như các thư viện javascript, font hoặc css được cộng đồng phát triển đã mang đến những package phổ biến trong RubyGem.
Chúng ta sẽ không dựa vào RubyGem của asset. Thay vào đó, chúng ta sẽ sử dụng Bower để quản lý. Bower được tạo bởi Twitter để quản lý font-end asset và hầu hết các thư viện, bao gồm cả module Angular.
Để cài được bower bạn cần chạy lệnh sau npm install -g bower
Bây giờ thì bower đã được cài đặt, chúng ta cần cài thêm gem bower-rails
, gem này sẽ là cầu nối giao tiếp của ứng dụng Rails và Bower (thêm gem này vào Gemfile)
Bower làm việc tương tự Bundler. Tiếp theo bạn chạy lệnh rake -T bower trên console
> rake -T bower
rake bower:cache:clean # Clear the bower cache ('bower cache clean')
rake bower:clean # Attempt to keep only files listed in 'main' of each component's bower.json
rake bower:install[options] # Install components from bower
rake bower:install:deployment[options] # Install components from bower using previously generated bower.json
rake bower:install:development[options] # Install both dependencies and devDependencies from bower
rake bower:install:production[options] # Install only dependencies, excluding devDependencies from bower
rake bower:list # List bower components
rake bower:resolve # Resolve assets paths in bower components
rake bower:update[options] # Update bower components
rake bower:update:prune[options] # Update existing components and uninstalls extraneous components
Bower có file Bowerfile tương tự như Gemfile. Đầu tiên bạn phải cài Boostrap, Boostrap là không bắt buộc, nhưng trong những ứng dụng demo này chúng ta phải sử dụng để xây dựng giao diện. Bạn thêm vào file Bowerfile hai dòng sau để có thể sử dụng được boostrap:
asset 'angular'
asset 'bootstrap-sass-official'
Và bây giờ bạn cài đặt thông qua rake task bower:install
> rake bower:install
bower.js files generated
/usr/local/share/npm/bin/bower install
bower bootstrap-sass-official#* not-cached git://github.com/twbs/bootstrap-sass.git#*
bower bootstrap-sass-official#* resolve git://github.com/twbs/bootstrap-sass.git#*
bower angular#* cached git://github.com/angular/bower-angular.git#1.2.13
bower angular#* validate 1.2.13 against git://github.com/angular/bower-angular.git#*
bower bootstrap-sass-official#* download https://github.com/twbs/bootstrap-sass/archive/v3.1.1.tar.gz
bower angular#* new version for git://github.com/angular/bower-angular.git#*
bower angular#* resolve git://github.com/angular/bower-angular.git#*
bower angular#* download https://github.com/angular/bower-angular/archive/v1.2.14.tar.gz
bower bootstrap-sass-official#* extract archive.tar.gz
bower angular#* extract archive.tar.gz
bower bootstrap-sass-official#* resolved git://github.com/twbs/bootstrap-sass.git#3.1.1
bower angular#* resolved git://github.com/angular/bower-angular.git#1.2.14
bower bootstrap-sass-official#* install bootstrap-sass-official#3.1.1
bower angular#* install angular#1.2.14
bootstrap-sass-official#3.1.1 bower_components/bootstrap-sass-official
angular#1.2.14 bower_components/angular
Bower được cài đặt phụ thuộc vào thư mục vendor/assets/bower_components
. Trông thư mục này có vẻ khá lạ lẫm nhưng nó cho phép bạn tách các thư viện được quản lý bởi Bower thành 3 phần
Trong phần cấu hình, bạn thêm vào file config/application.rb
các dòng sau
config.assets.paths <<
Rails.root.join("vendor","assets","bower_components")
config.assets.paths << Rails.root.join("vendor","assets","bower_components",
"bootstrap-sass-official","assets","fonts")
config.assets.precompile << %r(.*.(?:eot|svg|ttf|woff|woff2)$)
Trong file app/assets/javascripts/application.js bạn thêm vào dòng sau
//= require angular/angular
và bỏ đi
//= require turbolinks
Trong file app/assets/stylesheets/application.css.scss
bạn thêm vào 2 dòng sau
@import "bootstrap-sass-official/assets/stylesheets/bootstrap-sprockets";
@import "bootstrap-sass-official/assets/stylesheets/bootstrap";
Chạy ứng dụng cùng với Angular
1. Xử lý thẻ input
Vậy là chúng đã cài đặt xong môi trường, bây giờ chúng ta sẽ chạy ứng dụng nhỏ đầu tiên
Bạn tạo ra file controller là home_controller
class HomeController < ApplicationController
def index
end
end
Trên file app/views/home/index.html.erb
bạn thêm vào trong file
<div class="container-fluid" ng-app="receta">
<div class="panel panel-success">
<div class="panel-heading">
<h1 ng-if="name">Hello, {{name}}</h1>
</div>
<div class="panel-body">
<form class="form-inline">
<div class="form-group">
<input class="form-control" type="text" placeholder="Enter your name" autofocus ng-model="name">
</div>
</form>
</div>
</div>
</div>
Cuối cùng là bạn tạo ra file app.coffee
thêm vào trong file
receta = angular.module('receta',[
])
Và bây giờ bạn có thể chạy ứng dụng của mình rồi đấy, kết quả khi chạy ứng dụng là với bất kỳ thứ gì bạn điền vào thẻ input thì đều hiển thị ngay lên luôn màn hình mà ko cần bất kỳ nút click nào
2. Ứng dụng tìm kiếm trên Angular
Để làm được ứng dụng này chúng ta phải trải qua hai bước sau
a. Tạo ra giao diện tìm kiếm cơ bản trên view
Tạo ra file app/assets/javascripts/app.coffee.erb
, app.coffee có quyền truy cập đến asset_path helper
app.config([ '$routeProvider',
($routeProvider)->
$routeProvider
.when('/',
templateUrl: "<%= asset_path('index.html') %>"
controller: 'SomeController'
)
.when('/recipes/new',
templateUrl: "<%= asset_path('new.html') %>"
controller: 'SomeOtherController'
)
])
Để chạy được ứng dụng này bạn cần phải cài thêm Gemfile angular-rails-templates
và thêm vào Bowerfile angular-route
. Sau khi cài đặt thành công bạn thêm vào trong file /app/assets/javascripts/application.js
2 dòng sau:
//= require angular-route/angular-route
//= require angular-rails-templates
Trên file app/views/home/index.html.erb
bạn thêm vào
<div ng-app="receta">
<div class="view-container">
<div ng-view class="view-frame animate-view"></div>
</div>
</div>
Sử dụng ng-app để nói với Angular biết rằng ứng dụng cần được load và ng-view để chỉ ra nơi mà view có thể được render tới. Trong thẻ div view-container có chứa 2 class view-frame và animate-view để tạo ra những hình ảnh động nếu muốn, nhưng tạm thời chúng ta chưa cần quan tâm đến điều này.
Tiếp theo chúng ta cần cài đặt ứng dụng receta của Angular để có thể render view. Từ bây giờ chúng ta cần module angular-routes được cung cấp bởi angular-rails-templates
đã được cài trong Gemfile.
Tạo ra file app/assets/javascripts/app.coffee
receta = angular.module('receta',[
'templates',
'ngRoute',
'controllers',
])
receta.config([ '$routeProvider',
($routeProvider)->
$routeProvider
.when('/',
templateUrl: "index.html"
controller: 'RecipesController'
)
])
controllers = angular.module('controllers',[])
controllers.controller("RecipesController", [ '$scope',
($scope)->
])
Và việc cuối cùng trong phần tạo giao diện này là tạo ra file index.htm, file này sẽ được đặt trong thư mục mặc định là app/assets/javascripts/templates
được tạo ra bởi gem angular-rails-templates
<header class="row">
<h1 class="text-center col-md-6 col-md-offset-3">Find Recipes</h1>
</header>
<section class="row">
<form>
<div class="form-group col-md-6 col-md-offset-3">
<label for="keywords" class="sr-only">Keywords</label>
<input ng-model="keywords" name="keywords" type="text" autofocus class="form-control" placeholder="Recipe name, e.g. Baked Potato">
</div>
<div class="form-group col-md-6 col-md-offset-3 text-center">
<button ng-click="search(keywords)" class="btn btn-primary btn-lg">Search</button>
</div>
</form>
</section>
<hr>
<section class="row" ng-if="recipes">
<h1 class="text-center h2">Results</h1>
<ul class="list-unstyled">
<li ng-repeat="recipe in recipes">
<section class="well col-md-6 col-md-offset-3">
<h1 class="h3 col-md-6 text-right" style="margin-top: 0"><a href="#">{{recipe.name}}</a></h1>
<div class="col-md-6">
<button class="btn btn-info">Edit</button>
<button class="btn btn-danger">Delete</button>
</div>
</section>
</li>
</ul>
</section>
Chúng ta sử dụng ng-if để ẩn hoàn toàn kết quả nếu không có thứ gì trả về
Và giao diện sau khi tạo xong sẽ trông như thế này
b.Phần controller xử lý tìm kiếm
Tại file app/assets/javascripts/app.coffee
receta = angular.module('receta',[
'templates',
'ngRoute',
'controllers',
])
receta.config([ '$routeProvider',
($routeProvider)->
$routeProvider
.when('/',
templateUrl: "index.html"
controller: 'RecipesController'
)
])
recipes = [
{
id: 1
name: 'Baked Potato w/ Cheese'
},
{
id: 2
name: 'Garlic Mashed Potatoes',
},
{
id: 3
name: 'Potatoes Au Gratin',
},
{
id: 4
name: 'Baked Brussel Sprouts',
},
]
controllers = angular.module('controllers',[])
controllers.controller("RecipesController", [ '$scope', '$routeParams', '$location',
($scope,$routeParams,$location)->
$scope.search = (keywords)-> $location.path("/").search('keywords',keywords)
if $routeParams.keywords
keywords = $routeParams.keywords.toLowerCase()
$scope.recipes = recipes.filter (recipe)-> recipe.name.toLowerCase().indexOf(keywords) != -1
else
$scope.recipes = []
])
Vậy là chúng ta đã xây dựng xong ứng dụng tìm kiếm trên Angular
Tài liệu tham khảo
Bài viết này mình có tham khảo tại trang web
All rights reserved