Thêm và xóa field với Rails Nested Forms and AngularJS
Bài đăng này đã không được cập nhật trong 8 năm
Giới thiệu
Việc làm nested form trong rails là khá đơn giản, khi chúng được hỗ trợ khá nhiều. Và có khá nhiều bài viết mẫu và ví về việc thêm hay xóa bớt các field được viết bằng jquery.
Nhưng giả sử bạn không muốn dùng jquery vì lo ngại về tốc độ xử lý, bạn nghĩ ngay đến angularJS nhưng lại chưa biết cách sử dụng nó kết hợp với Rails Nested Forms. Trong phần này, chúng ta sẽ cùng làm ví dụ nhỏ dưới đây để tìm hiểu cách dựng form nested với AngularJS
Tạo model
Giả sử ta có 2 model: Plan và Poll. Với Plan là cha, còn Poll là con.
Trong model Plan ta sẽ khai báo:
accepts_nested_attributes_for :polls
# app/models/plan.rb
class Plan < ActiveRecord::Base
has_many :polls
accepts_nested_attributes_for :polls
end
# app/models/poll.rb
class Poll < ActiveRecord::Base
belongs_to :plan
end
Tạo controller
Trong controller của Plan ta sẽ build sẵn 1 poll mặc định ban đầu.
# app/controllers/plans_controller.rb
class PlansController < ApplicationController
def new
@plan = Plan.new
@poll = @plan.polls.build
end
def create
@plan = Plan.new plan_params
@plan.save
end
end
View
# app/views/plans/new.html.erb
<div ng-app>
<%= form_for @plan do |form| %>
<div ng-controller="PlanCtrl as vm" ng-init="vm.polls = [{title: ''}]">
<div ng-repeat="poll in vm.polls">
<%= form.fields_for :polls, @poll, child_index: '{{$index}}' do |poll_form| %>
<%= poll_form.text_field :title, id: 'plan_poll_{{$index}}', "ng-model": "poll.title" %>
<% end %>
<a href="#" ng-click="vm.remove($index)" ng-show="vm.isRemovable()">Remove</a>
</div>
<a href="#" ng-click="vm.add()">Add</a>
</div>
<% end %>
</div>
Ta khai báo 1 mảng polls = [{title: ''}]
để chạy vòng lặp. Mỗi lần thêm hoặc xóa field là thêm hoặc xóa 1 phần tử của mảng này.
AngularJS controller
Các hàm thêm và xóa field được viết trong AngularJS controller.
// app/assets/javascripts/plans.js
function PlanCtrl() {
vm.isRemovable = function() {
return vm.polls.length > 1;
};
vm.add = function() {
vm.polls.push({title: ''});
};
vm.remove = function(index) {
vm.polls.splice(index, 1);
};
}
Giải thích các hàm:
$scope.isRemovable = function() {
return $scope.polls.length > 1;
};
Hàm isRemovable()
để kiểm tra xem field có thể xóa hay không. Khi số phần tử của poll lớn hơn 1 thì có thể xóa.
$scope.add = function() {
$scope.polls.push({title: ''});
};
Hàm add()
để thêm phần tử vào poll, tạo thêm 1 lần lặp, đồng nghĩa với việc thêm field.
$scope.remove = function(index) {
$scope.polls.splice(index, 1);
};
Hàm remove()
để xóa phần tử trong poll, bỏ đi 1 lần lặp, đồng nghĩa với việc xóa field.
Tài liệu tham khảo
https://tatey.com/2013/01/13/adding-and-removing-children-with-rails-nested-forms-and-angularjs/
Phần 2
Ở phần 2, chúng ta sẽ làm ví dụ về việc tạo plan lỗi, và phải render lại đúng trạng thái các field và làm chức năng update. Phần 2 sẽ được viết tiếp trong tháng sau.(chao)
All rights reserved