Building Rails application with EmberJS

1.Giới thiệu về EmberJS

Hiện nay, xu thế phát triển chung của các ứng dụng web là phân tách riêng biệt hai phần: Front-end và Back-end để nâng cao hiệu năng hoạt động của web. Phía server (Back-enduery) bao gồm Controller và Model thường chỉ đóng vai trò truy xuất và quản lý dữ liệu vào ra của ứng dụng trong khi phía View sẽ hiện thị dữ liệu cho người sử dụng. Tuy nhiên, các ứng dụng web hiện nay đòi khỏi khả năng tương tác động tốt hơn, không chỉ gói gọn trong 7 action RESTful cơ bản. Để có thể giải quyết vấn đề này, một số Framework dành cho client-side đã được xây dựng, điển hình có thể kể tới AngularJS, EmberJS, BackboneJS. Trong blog này, Framgia dev xin phép được giới thiệu cơ bản về EmberJS, cách xây dựng một ứng dụng của EmberJS dựa trên Framework Ruby On Rails.

EmberJS là một client-side Framework được viết dựa trên ngôn ngữ Javascript (Chắc chắn rồi). Đặc điểm nổi bật của Ember chính là khả năng đồng bộ. Các đối tượng của trang web sẽ được gắn với Framework để có thể update các đối tượng mà không cần quan tâm tới việc quan hệ giữa các thành phần trang web như thế nào. Điều này mang lại hiệu quả cho cả người sử dụng lẫn nhà phát triền (Dev) khi các sự kiện cùng dữ liệu trên page được quản lý theo một cách dẽ dàng hơn

2.Xây dựng Rails application sử dụng EmberJS

2.1 Cấu trúc thư mục của EmberJS

EmberJS có cấu trúc thư mục giống như mô hình MVC, dưới đây là các folder nằm trong thư mục app/assets/javascript:

  • app/ - chứa tất cả các javascript file cần thiết và các template liên quan tới Ember
  • app/app.js - khai báo biến ứng dụng global được mở rộng từ EmberEmber.Application
  • app/models/ - chứa các class model
  • app/controllers/ - quản lý và điều khiển tài nguyên
  • app/views/ - chứa các class view
  • app/templates/ - chứa các template
  • app/helpers/
  • vendor/
  • lib/

2.2 Thiết lập EmberJS cho Rails

2.2.1 Khởi tạo

Gemfile

gem 'ember-rails'

Bundle

bundle instal

Khởi tạo cây thư mục trong app/assets/javascripts/

cd app/assets/javascripts
mkdir app app/controllers app/helpers app/models app/templates app/views lib vendor

Thêm vào file application.js để có thể thực hiện load pipeline

//= require jquery
//= require jquery_ujs
//= require ./vendor/ember
//= require ./vendor/ember-rest
//= require_tree ./lib
//= require app/app
//= require_tree ./app/models
//= require_tree ./app/controllers
//= require_tree ./app/views
//= require_tree ./app/helpers
//= require_tree ./app/templates

Download EmberJS từ trang chủ và thêm vào app/assets/javascripts/vendor/

Tạo ứng dụng ember trong app/assets/javascripts/application.js

App = Ember.Application.create();

2.2.2 Rails server

Để quá trình thực hiện đơn giản hơn, có thể sử dụng option generate scaffold của Rails

rails g scaffold

Các thiết lập cơ bản dành cho model và controller như sau:

  • Model: app/models/contact.rb
    class Contact < ActiveRecord::Base
      validates :first_name, :presence => true
      validates :last_name, :presence => true
    end
  • Controller: app/controllers/contacts_controller.rb
    class ContactsController < ApplicationController
      # GET /contacts
      # GET /contacts.json
      def index
        @contacts = Contact.all
        respond_to do |format|
          format.html # index.html.erb
          format.json { render json: @contacts }
        end
      end

      # GET /contacts/1.json
      def show
        @contact = Contact.find(params[:id])
        respond_to do |format|
          format.json { render json: @contact }
        end
      end

      # POST /contacts.json
      def create
        @contact = Contact.new(params[:contact])
        respond_to do |format|
          if @contact.save
            format.json { render json: @contact, status: :created, location: @contact }
          else
            format.json { render json: @contact.errors, status: :unprocessable_entity }
          end
        end
      end

      # PUT /contacts/1.json
      def update
        @contact = Contact.find(params[:id])

        respond_to do |format|
          if @contact.update_attributes(params[:contact])
            format.json { render json: nil, status: :ok }
          else
            format.json { render json: @contact.errors, status: :unprocessable_entity }
          end
        end
      end

      # DELETE /contacts/1.json
      def destroy
        @contact = Contact.find(params[:id])
        @contact.destroy
        respond_to do |format|
          format.json { render json: nil, status: :ok }
        end
      end
    end
  • Routes
    EmberRestExample::Application.routes.draw do
      root :to => 'contacts#index'
      resources :contacts
    end

2.2.3 Front end

  • Model: app/assets/javascripts/app/models/contact.js
    App.Contact  = Ember.Resource.extend({
      resourceUrl: '/contacts',
      fullName: Ember.computed(function() {
        return this.get('first_name') + '' + this.get('last_name');
      }).property('first_name', 'last_name')
    });
  • Controller: app/assets/javascripts/app/controllers/contacts.js
    App.contactsController = Ember.ResourceController.create({
      resourceType: App.Contact
    });
  • Views: ListContactsView :app/assets/javascripts/app/views/contacts/list.js
    App.ListContactsView = Ember.View.extend({
      templateName:    'app/templates/contacts/list',
      contactsBinding: 'App.contactsController',

      refreshListing: function() {
        App.contactsController.findAll();
      }
    });

ShowContactView: app/assets/javascripts/app/views/contacts/show.js

    App.ShowContactView = Ember.View.extend({
      templateName: 'app/templates/contacts/show',
      classNames:   ['show-contact'],
      tagName:      'tr'
    });
  • Template: Handlebar List: app/assets/javascripts/app/templates/contacts/list.handlebars
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
        </tr>
      </thead>
      <tbody>
      {{#each contacts}}
        {{view App.ShowContactView contactBinding="this"}}
      {{/each}}
      </tbody>
    </table>
  • Show: app/assets/javascripts/app/templates/contacts/show.handlebars
    <td>
    {{contact.id}}
    </td>
    <tdclass="data">{{contact.fullName}}</td

2.2.4 Hoàn thiện

Sau khi đã xây dựng cơ bạn ở phía Server, ta cần phải thực hiện những thao tác cuối cùng trong các file .erb: app/views/contacts/index.html.erb:

    <h1>Contacts</h1>
    <script type="text/x-handlebars">
      {{ view App.ListContactsView }}
    </script>

    <script type="text/javascript">
      $(function() {
        App.contactsController.loadAll(<%= @contacts.to_json.html_safe %>);
      });
    </script>

3 Kết Luận

Quá trình khởi tạo ban đầu để xây dựng một ứng dụng Rails App sử dụng EmberJS phải trải qua rất nhều bước phức tạp, đòi hỏi dev phải có kiến thức vững vàng không chỉ về mô hình MVC mà còn cả những kỹ năng lập trình view dựa trên javascript. Hiện nay đã có tool hỗ trợ debugs EmberJS trên Google Chrome Ember Inspector. Tuy nhiên, lợi ích mà EmberJS mang lại là rất lơn, không chỉ về sự đa dạng trên client-side mà còn hiệu năng hoạt động của Website.


All Rights Reserved