Pull to refresh

CRUD-приложение на Ext JS и Ruby on Rails за 7 минут

Reading time5 min
Views22K
Original author: Max Gorin
Это обновленная версия устаревшего поста.

Этот пост покажет вам простые шаги по созданию менеджера задач TODO с использованием Ext JS, Ruby on Rails и Netzke. Это займет у вас приблизительно 7 минут, и если вам заранее любопытно, стоит ли оно того, загляните прямиком в секцию «Обсуждаем результаты» (кстати, самую большую). Наша цель заключается в создании веб-приложения которое позволит нам добавлять, редактировать и удалять задачи TODO, так же как и помечать их как завершенные. В дополнение к этому вы сможете сортировать задачи, делать поиск по ним, редактировать несколько задач одновременно — и это еще не все. Если хотите, засекайте время на секундомере — и давайте приступим.





При создании этого туториала, я использовал следующие версии библиотек: Rails 3.2.8, netzke-core v0.8.0, netzke-basepack v0.8.0, Ext JS 4.1.1a — а также Ruby 1.9.3 и Mac OSX Mountain Lion

Первоначальные шаги


Создаем новое Rails-приложение:

$ rails new netzke_task_manager && cd netzke_task_manager


Добавляем Netzke в Gemfile:

gem 'netzke-core', '~>0.8.0'
gem 'netzke-basepack', '~>0.8.0'


Устанавливаем гемы:

$ bundle install


Линкуем библиотеку Ext JS, и (что необязательно) иконки FamFamFam, в public/extjs и public/images/icons соответственно. Например (например!):

$ ln -s ~/code/extjs/ext-4.1.1 public/extjs
$ mkdir public/images
$ ln -s ~/assets/famfamfam-silk public/images/icons


Укажем рауты Netzke и откомментируем корневой раут в config/routes.rb:

NetzkeTaskManager::Application.routes.draw do
  netzke
  root to: "welcome#index"
end


Сгенерируем контроллер welcome:

$ rails g controller welcome index


Не забудьте удалить public/index.html.

В app/views/layouts/application.html.erb заменим дефолтный код, подключающий JavaScript и стили, хелпером load_netzke. Результат должен выглядеть примерно вот так:

<!DOCTYPE html>
<html>
<head>
  <title>Netzke Task Manager</title>
  <%= load_netzke %>
  <%= csrf_meta_tag %>
</head>
<body>
<%= yield %>
</body>
</html>


Заметьте, что хелпер load_netzke — это все, что необходимо для подключение скриптов и стилей как Netzke, так и самой Ext JS.

Прошло 3 минуты — и мы готовы приступить к по-настоящему интересной части!

Создание модели


Давайте создаим модель Task, у которой будут аттрибуты name, priority, notes, due_date и флаг done:

$ rails g model Task done:boolean name notes:text priority:integer due:date


Обновим схему нашей БД:

$ rake db:migrate


Мы хотим чтобы наши задачи, как минимум, всегда имели какое-то имя, поэтому давайте добавим соответствующую валидацию (файл app/models/task.rb):

class Task < ActiveRecord::Base
  attr_accessible :done, :due, :name, :notes, :priority
  validates :name, presence: true
end


Создаем грид-компонент Tasks


Давайте создадим наш первый компонент Netzke, унаследовав его от полнофункционального Netzke::Basepack::Grid. Но прежде нам нужно создать директорию app/components:

$ mkdir app/components


В этой директории создаем файл tasks.rb со следующим содержимым:

class Tasks < Netzke::Basepack::Grid
  def configure(c)
    super
    c.model = "Task"
  end
end


Наш компонент — это класс Ruby, унаследованный от Netzke::Basepack::Grid, и сконфигурированный на использование ранее созданной модели Task. Теперь нам необходимо встроить созданный компонент во view нашего приложения. В файле app/views/welcome/index.html.erb замените код по умолчанию на следующую строчку:

<%= netzke :tasks, height: 400 %>


Запустим сервер:

$ rails s


… и посмотрим, как это выглядит в браузере по адресу http://localhost:3000/:



Наше приложение работает и с первого взгляда вполне неплохо выглядит. Через минуту я предоставлю вам впечатляющий список того, какие возможности оно предоставляет, но сначала давайте внесем небольшие поправки, чтобы улучшить вид приложения (у нас все еще достаточно времени для этого).

Netzke::Basepack::Grid, от которого унаследован наш грид, гибко конфигурируется. Давайте внесем 4 простых улучшения:

  • обозначим, какие колонки мы ходим видеть (скроем created_at и updated_at)
  • изменим заголовок колонки «Due» на «Due on»
  • сконфигурируем колонку «Notes» так, чтобы она заполняла всю оставшуюся ширину, пользуясь свойством flex из Ext.grid.column.Column
  • воспользуемся конфигурационным параметром scope нашего грида, чтобы исключить те записи, в которых выставен флаг done


Окончательный код нашего компонента будет выглядеть так:

class Tasks < Netzke::Basepack::Grid
  def configure(c)
    super
    c.model = "Task"
    c.columns = [
      :done,
      :name,
      {name: :notes, flex: 1},
      :priority,
      {name: :due, header: "Due on"}
    ]
    c.scope = {done: [nil, false]}
  end
end


Отлично. Воспользуемся оставшимися двумя минутами, чтобы привнести последнюю, чисто визуальную, правку. Чтобы поместить наш грид в середину страницы, добавим пару стилей в app/views/layouts/application.html.erb, сразу после хелпера load_netzke:

<style type="text/css" media="screen">
  h1 { text-align: center; margin: 10px;}
  .netzke-component { width: 800px; margin: auto; }
</style>


Добавим заголовок h1 в app/views/welcome/index.html.erb:

<h1>Incomplete tasks</h1>
<%= netzke :tasks, height: 400 %>


Ну, вот и все! Можно останавливать секундомер и обсуждать результаты:



Обсуждаем результаты


Поскольку Netzke::Basepack::Grid — полнофункциональный компонент, мы получаем кучу функционала, не написав для этого ни строчки кода. Давайте взглянем подробнее.

Автоматическое определение типов полей

В нашем приложении мы создали поля в модели Task с несколькими разными типами: integer, boolean, string, text и date. Каждое поле автоматически получает колонку, поддерживающую соответствующий тип (например, вы не сможете ввести буквы в поле priority, поле date снабжено календарем, и т.д.).

Страницы

Даже если таблица tasks содержит десятки тысяч записей, это не представляет проблемы для грида Netzke благодаря встроенной поддержке страниц.

Возможность редактировать несколько строк одновременно

Добавление, обновление и удаление нескольких записей сразу осуществляется без труда:



Контекстное меню

Некоторые функции кнопок в нижней панели грида продублированы в контекстном меню:



Поддержка валидаций Rails

Валидации Rails принимаются во внимание:


Сортировка записей на сервере

Кликните по заголовку колонки, чтобы выполнить сортировку записей:


Фильтрация записей на сервере

«Умные» фильтры встроены по умолчанию в каждую колонку, в соответствии с типом поля.

Для даты:



Для приоритета:



Добавление и редактирование записей через форму


Иногда добавление или редактирование записей проще выполнять через форму. Netzke предоставляет вам и такую возможность (редактирование нескольких записей также поддерживается — просто выделите несколько строк и нажмите «Edit in form»).



Развернутый поиск с поддержкой сохранения запросов

Нажмите кнопку Search для вызова редактора сложных запросов:



Лишь верхушка айсберга

То, о чем вы узнали — это лишь очень маленькая часть того, что может Netzke. По сути, я лишь показал, как использовать заранее созданный компонент, построенную на основе невероятно мощной платформы Netzke Core, которая, среди прочего, позволяет комбинирование компонентов в новые (составные) компоненты, поддерживает динамическую загрузку компонентов с сервера, гибкое взаимодействие между клиентской и серверной частями компонента — и многое другое, что делает Netzke, использующей мощь Ext JS и Rails, идеальной платформой для создания невероятно сложных одностраничных веб-приложений.

В продолжение этого поста, я покажу вам, как просто поместить 3 экземпляра нашего компонента на панель закладок, каждый из которых будет показывать свою выборку задач: завершенные задачи, незавершенные задачи, и все задачи одновременно. Смотрите следующую часть туториала.

Примечание от переводчика: компоненты из Netzke Basepack поддерживают русскую локализацию.
Tags:
Hubs:
Total votes 47: ↑35 and ↓12+23
Comments42

Articles