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

Автор оригинала: Max Gorin
  • Перевод
  • Tutorial
Это обновленная версия устаревшего поста.

Этот пост покажет вам простые шаги по созданию менеджера задач 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 поддерживают русскую локализацию.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 42

    +1
    Офигенно! А для PHP что-то подобное есть?
    +1
    А с использованием scaffold такое приложение можно создать за 1 минуту безо всяких Ext JS.

    P.s. правда, оно будет страшненькое %)
      +3
      Не только «страшненькое», это даже не главное. Здесь у нас сортировка, pagination, поиск, редактирование inline, и прочее. И — самое главное — нет ни сгенерированного View, ни Controller, что очень критично для приложений с сотнями моделей (подробнее про это в моих комментариях ниже).
        0
        + twitter bootstrap = 2 минуты и не такое страшненькое )
        0
        Но зачем?
          +5
          Всерьез задумавшись над тем, что вам ответить, я в результате уперся в вопрос о смысле жизни…

          Вы, пожалуйста, поосторожнее с такими вопросами! :)
          +3
          Судя по примеру приложения по ссылке с гитхаба, тут та же беда, что и со многими другими приложениями, которые используют Ext 4+ — пишется куча вьюх/моделей/хранилищ/контроллеров, затем они по мере неоходимости подгружаются с помощью Ext.Loader (или, в данном случае, каким-то его Netzke-аналогом).

          В итоге получается — жмем кнопку чтобы вызвать форму редактирования, уходит запрос на сервер, юзер ждет. Через какое-то время (в зависимости от качества интернетов и всякого такого) форма догружается и появляется на экране.

          Юзер (и часто разраб, если он не еще не вник в Ext, а только начинает) делает вывод что Ext это медленно и неповоротливо.
          В большинстве случаев 4-й экст есть смысл использовать только в связке с Sencha CMD. Ну или руками собирать все в кучу и скармливать в какой-нибудь closure compiler. Но это муторно.
            0
            По нажатию на вызов формы редактирования можно мгновенно (ну, или как получится у ExtJS) показывать пустую/полупустую форму и натягивать на неё маску «Loading», попутно отправляя AJAX-запрос за данными (точнее, сконфигурировать запрос данных из нужного хранилища, которое уже само инициирует или AJAX-запрос, или чтение из памяти, или ещё что-то), которые нужно отобразить в этой форме. В принципе, можно сконфигурировать один раз это, и onShow форма будет сразу показывать эту маску с каким-то текстом, а по завершению загрузки данных (или же после их обработки перед показом, тут уж как задумает программист) её убирать.

            Если скорость доступа к данным большая, а обработка данных занимает небольшое время, то иногда можно эту маску и не увидеть вообще. А если какие-то проблемы со связью или пересылаются/обрабатываются большие объёмы данных, то пользователь сразу видит, что вот он, интерфейс с нужными полями, но данных там ещё нет, и крутится какое-то изображение, показывающее, что идёт процесс загрузки данных.
              +1
              А зачем запрашивать данные для формы редактирования у сервера? Они же есть в хранилище грида.
              Там даже при нажатии на «Add in form» летит запрос на сервер и приходится ждать подгрузки формы.
                0
                Хорошее наблюдение!

                Иногда редактирование в форме не нужно, и чтобы не загружать сразу лишний JS код для формы, его подгрузка сделана динамической. Кстати, JS для класса формы подгружается только первый раз, после чего кэшируется, и с сервера грузится уже только собственно раскладка полей. Это дает нам гибкость в принятии решения на сервере, какие именно поля отображать в форме, что иногда может меняться прямо в процессе работы приложения. И, конечно, поля в форме и колонки в гриде могут отличаться (часто так и происходит) — это конфигурируется в классе грида.

                Однако, запрос на сервер при нажатии Add in form воможно отключить, если указать, что форма должна загружаться eagerly вместе с гридом. Это конфигурируется тоже.
                  0
                  Ну ок, наверное нет смысла развивать дискуссию по этому поводу, хотя я все же остаюсь приверженцем сборки приложения и используемых компонентов экста в один скрипт )

                  И, конечно, поля в форме и колонки в гриде могут отличаться (часто так и происходит) — это конфигурируется в классе грида.


                  Колонки грида и поля формы да, могут.
                  Я люблю толстые модели и тонкие контроллеры, поэтому поступил следующим образом — в базовом классе модели, от которого наследуются все остальные модели, описал метод getEditForm(). Если для модели установлено свойство editForm (например: editForm: 'app.view.User.edit'), то возвращется ее инстанс с загруженным record, иначе — создается и возвращается дефолтная форма редактирования, в которой присутствуют все поля модели, для которых не установлен признак editable: false.

                  В итоге получается довольно удобно и гибко — по нажатию кнопки в контроллере достаточно дернуть record.processEdit(), который, в свою очередь, сделает нужные проверки, покажет форму и т.д.
                  Учитывая что я тоже испорльзую кодогенераторы (чаще всего работаю с Yii и просто добавил в gii нужные генераторы), процесс развертки CRUD приложения занимает примерно столько же времени — достаточно натравить эти самые генераторы на БД.

                  Но это уже в рамках обмена опытом (хотя в формате комментария наверное не очень понятно получилось) — не сочтите за критику. А в это приложение было бы неплохо еще добавить возможность открыть несколько пунктов меню одновременно (например в отдельных табах), их сохранение между перезагрузками страницы, и stateful для гридов.
                    +1
                    Обмен опытом всегда интересен!

                    Похоже, вы нашли вполне интересный и работающий способ отображения форм для моделей.

                    Против кодогенераторов я выступаю только по той причине, что когда в приложении сотни моделей, кодогенераторы приводят к огромному количеству дуплицированного кода. Чтобы добавить/улучшить фичу во всех 100 гридах в приложении на Нецке, необходимо просто подправить Netzke::Basepack::Grid (или унаследованный от него свой грид, служащий базой для всех остальных гридов). А в случае со сгенерированным кодом — исправлять придется в 100 местах.

                    возможность открыть несколько пунктов меню одновременно (например в отдельных табах), их сохранение между перезагрузками страницы, и stateful для гридов

                    Да, все это легко делается с Netzke, см, например, netzke-demo.herokuapp.com или yanit.heroku.com.
                      0
                      А в случае со сгенерированным кодом — исправлять придется в 100 местах.


                      Ну вот поэтому я и оговорился, что в формате комментария ничерта не понятно )
                      Там генерится специфичная конфигурация — поля моделей, колонки гридов и всякое такое. Все общее — в базовых классах моделей/контроллеров. При этом в конкретном случае все можно переопределить.

                      У меня давно назрело желание по этому поводу накатать статью(и), т.к. в рунете не оч много вменяемой инфы по архитектуре экстовых приложений вообще, и Sencha CMD в частности. Да все никак время выбрать не могу. А в комментах, конечно, особо не объяснишь ничего.
                        0
                        Теперь понятнее, и в этом случае мы на одной волне, просто нашли разные подходы, которые было бы интересно сравнить в деталях — с удовольствием бы почитал статью.
                          0
                          Окей, постараюсь не затянуть.
                    0
                    Кстати, JS для класса формы подгружается только первый раз, после чего кэшируется, и с сервера грузится уже только собственно раскладка полей.


                    В случае фаерфокса, если не включен дисковый кеш, а именно browser.cache.disk.enable в about:config, то этот механизм не работает, фф не шлёт никаких if-modified-since, а простым гетом каждый раз загружает яваскрипты.
                    Честно говоря, не заметил, когда произошло выключение этой опции, столкнулся совершенно случайно, когда пожаловался клиент что наблюдает значительные тормоза при открытии страницы через gsm модем где-то далеко от цивилизации.
                    Ещё бы, там почти 4Мб было. После сенча цмд — стало полтора мб, стало лучше, но всё так же неудобно ждать несколько минут. Дальнейший разбор выявил причины.
                      0
                      Я имел в виду механизм кэширования встроенный в Netzke. Работает он так: когда я хочу динамически подгрузить, например, грид — для этого нужен Ext JS код самого класса компонента, плюс конфигурация для создания его образца (например, где будет указано, какие колонки должны быть отображены). И то, и другое, подгружается с сервера. JS эвалюируется, после чего класс оказывается объявлен в браузере. В следующий раз, когда нужен грид (по-другому сконфигурированный — например, привязанный к другой модели), с сервера загружается уже только конфигурация, потому что повторно эвалюировать сам класс необходимости нет.
                        0
                        А, невнимательно прочел. Я о наболевшем (-
                  0
                  Да, это один из воможных вариантов. Я выбрал сделать чуть по-другому: показывать маску Loading в самом гриде, пока загружается и код для формы (только первый раз, после чего кэшируется), и то, что в ней нужно отобразить. Если скорость доступа большая, то маску действительно можно и не увидеть.
                  0
                  пишется куча вьюх/моделей/хранилищ/контроллеров

                  Именно этого Netzke позволяет избежать. Конечно, создания моделей не избежишь, по-крайней мере в Рельсах, но Views и Controllers становятся не нужны, что освобождает нас от огромного количества не DRY кода. Взгляните, сколько кода нам понадобилось, чтобы создать грид-компонент, который работает с данной моделью — ок 14 строк. Ни одного View или Controller. Как это возможно? Благодаря тому, что вся View/Controller-логика — внутри Netzke::Basepack::Grid. И все, что нам нужно — унаследовать от нее (легко ли унаследовать View в Рельсах?..) и нужным образом сконфигурировать. Вся сортировка, поиск, автоматическое определение полей, даже конфигурация колонок налету (что не попало в этот пост) и т.д. — все это внутри Netzke::Basepack::Grid, и в этом сила компонентного подхода.

                  Это очень критично для сложных приложений, использующих сотни моделей (смотрите, например, мою заявку на EuRuKo — к сожалению, на английском).

                  Что касается того, что какие-то части приложения подгружаются динамически — это вовсе не обязательно с Нецке и остается на усмотрении разработчика. Когда в приложении, к примеру, сотни моделей (это не преувеличение, я работал с таким), «просто» сгенерировать Ext JS приложение целиком — это получилось бы очень, очень много кода, загрузка (и выполнение в браузере) которого заняла бы слишком много времени. Нецке же позволяет разработчику решать, что загружается сразу, а что позже, по запросу пользователя. Те же формы — они не обязаны загружаться с сервера каждый раз, я в одном из комментариев ниже подробнее про это написал.

                  Нецке разрабатывалась как-раз с расчетом делать быстрые Ext JS-приложения — именно этому способствуют встроенные механизмы кэширования JS классов, динамическая подгрузка кода компонентов, мультиплексирование запросов на сервер от нескольких компонент (с помощью Ext.Direct) и др.
                    0
                    Ну я, кажется, понял — тут расчет на быстрое поднятие CRUD-да без необходимости особой переконфигурации/изменения логики приложения.
                    У меня просто немного другой случай — нужно быстро поднимать морды для работы с данными (например бухгалтерская аналитика, закупки, сметы). Причем у каждого заказчика довольно специфическая логика и бизнес процессы, да и просто, как они это называют — «хотелки», под которые приложения после кодогенераторов нужно нужно подстраивать.

                    В этом случае отказ от MVC экста сильно чреват — завтра у них будет новая «хотелка» или изменения в бизнес-процессах, и будет армагеддон, если я описывал логику в гридах.
                    Поэтому поднялся фреймворк приложения — обработка меню, смена языка/тем/ интерфейса, базовые классы, кодогенератор. Приложение генериться, логика/вьюхи подтягиваются, sencha app build — на сервер.
                    Просто разные сферы применимости.
                      0
                      Грид — это всего лишь пример компонента, и, конечно, в него совершенно неуместно совать бизнес-процессы, не связанные с обработкой конкретной модели.

                      А вот если создать комплексную компоненту, которую условно назовем Application, которая будет содержать в себе «самый верх» бизнес-логики приложения (например, загрузка других компонент, сравнимо с Views), всевозможные меню, компонент дерево-эксплорер (к примеру), и любое количество других (возможно, также комплексных) компонент, в каждом из которых реализован свой кусок логики приложения — вот тогда и получится гибкое, стройное приложение, для упрощения создания которого я и написал Netzke.

                      Другими словами: каждый компонент в приложении должен отвечать за четко определенный набор задач, как-можно более изолированный от остального приложения. В этом смысл компонентного подхода к созданию приложений — и это то, чего мне не хватало в Рельсах (повторюсь: когда вопрос касался сложных одностраничных приложений).
                  0
                  Извиняюсь, но слово «компонента» обычно используетя в естественных науках, например в математике, физике. В остальной жизни, в т.ч. и программировании, эта штука мужского рода — компонент.
                    0
                    Действительно! Это открытие для меня, я подправлю пост.
                    0
                    Увы на первый вопрос в списке так ни кто и не ответил, поэтому я продублирую вопрос. А есть ли что то подобное для PHP, или система создания гридов — с возможностью задания фильтров по столбцам, или вообще универсальные фильтры, которые можно выводить перед любой таблицей?
                      0
                      Был опыт нескольких больших проектов с Ext JS, код выглядит жутковато и работает медленно. По возможности, стараюсь избегать этого зверя.
                        +1
                        Согласен с оценкой того, как выглядит код. В этом смысле Netzke довольно-таки облегчает жизнь:

                        1) Netzke-компонент, будучи однажды написанным (для чего наверняка понадобится знание Ext JS), после этого встраивается в Рельсы (или другие компоненты), путем использования преимущественно Руби. Т.е. JS «заворачивается» в компоненту, и основным ее интерфейсом становится ее Руби класс (в Руби происходит, в частности, конфигурация клиентской части компоненты, и код читается достаточно просто). Т.е. необходимость «связываться» с Ext JS значительно снижается, соответственно процент экспертов в Ext JS в команде разработчиков может быть также снижен.

                        2) Код выглядит более структурировано: github.com/netzke/netzke-core#what-is-a-netzke-component

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

                        Насчет оценки скорости сложно как-то прокомментировать, потому что скорость сильно зависит и от качества кода тоже, от выбранных подходов в решении разных мини-задач (и в том числе и от серверной части тоже). Если бы было более определенное описание какой-то проблемы с быстродействием Ext JS — тогда было бы возможно ее обсудить.
                          0
                          работает медленно и выглядит жутковат просто от не умения готовить.
                          0
                          Эххх, а потом потребуется сделать, например, галочку, которая связывет нижнюю строку к верхней и начнется то, за что мы реально получаем деньги :)
                            0
                            Спасибо за интересный компонент и интересную статью. А будет ли перевод второй части?
                              0
                              Пытался использовать ExtJS для системы документооборота предприятия. Столкнулся с кучей конкурирующих с RoR особенностей, нафиная с формирования запроса. В некторых случах приходится модифицировать контроллер, к чему ExtJS готов, но по-своему, и его точка зрения не совпадает с точкой зрения RoR.
                              С другой стороны, RoR разработчикам доступны компоненты, которые сразу дружат с рельсами и друг с другом, это и kaminary, и boootstrap, и ransack, и т.д., которые успешно решают задачи предоставления datagrid, однако уровень абстракции гораздо выше, чем у ExtJS которые скорее диктует RoR что и как нужно делать, и модель conventions over configuration сразу разрушается.
                              Т.о. мне ExtJS видится подходящим для чего угодно, кроме RoR. Уж лучше тогда backend сразу писать на node.js, потому как в нашем случае, рельсы будут скорее тормозить процесс в виду идеологической несовместимости с ExtJS.
                                0
                                Не очень понял — а в чем у них идеологическая несовместимость? Если речь идет об одностраничном приложении, то просто клиент с сервером меняются, например, json-ом. А какая у кого идеология не особо важно.
                                В чем, например, разница — будете вы JQuery-вскими $.ajax () на сервер с рельсами ходить, или экстовым прокси?
                                  0
                                  Ну например в том, что ExtJS 3 был не restfull, возможно что-то изменилось в 4-й версии, но осадочек остался. А если с рельсами общаться не как с REST-сервисом, то нужно оверрайдить кучу рабочего функционала. Если мы любим руби, то удобно воспользоваться каким-то rack-based фреймворком, но не rails(с оговоркой на ExtJS3).
                                    0
                                    3-й экст держал REST.
                                      0
                                      Обещаю попробовать ExtJS в следующем проекте с админкой, добавлю в напоминание перечислить Вам весь список граблей на которые наступлю. Да даже в виде статьи это можно будет изобразить.
                                        0
                                        Окей, авансировал.
                                        Только при этом постарайтесь в нем разобраться — от обилия возможностей легко самому себе граблей под ноги разложить. По пути можете стучаться в личку/скайп, если что.
                                          0
                                          Какой неожиданный разворот моего неосторожного комментария :)
                                            0
                                            Просто слухи о монструозности экста обычно сильно преувеличены )
                                            Но да, у него порог вхождения повыше чем у многого другого, и чтобы сделать что то стоящее нужен некоторый опыт.
                                      0
                                      Вообще, поддержка REST-архитектуры она скорее на разрабе. Если он сделает restfull — это будет restfull приложение. От экста ту мало что зависит, он для этого давал все возможности.
                                  0
                                  В рецепте сказано взять чистую кастрюлю, но не сказано где. (из анекдота)
                                  Откуда качать ExtJS и иконки, находится через поисковики, но лучше бы в статье приводились ссылки на их скачивание. Или уточнялось, что ExtJS нужна ровно 4.1.* не больше не меньше.

                                  Для меня оказалось не тривиально найти 4.1.* версию ExtJS, на их сайте www.sencha.com/products/extjs/download/
                                  Version 4.1.3 and Version 3.4.1 are available to Sencha Support subscribers

                                  Минимальная подписка 600$, не наш путь.

                                  4.2.1.883 (Working in Open Source?)

                                  После скачивания, подлинковывания в public/extjs, и при обращении к localhost:3000 получил:
                                  No such file or directory - /home/charger/projects/netzke_task_manager/public/extjs/examples/ux/CheckColumn.js

                                  Related Downloads: Ext JS 4.0.7

                                  получаю белый лист в браузере и ошибку «Netzke: Ext JS 4.1.x required (you have 4.0.7).»

                                  скачал таки 4.1.1а с офф. сайта обнаружив через гугл. Ну и сайт у ExtJS.
                                  В итоге заработало но в 7 минут явно не вложился.
                                    0
                                    Спасибо за конструктивный отзыв!

                                    Я активно работаю над апдейтом Netzke, который будет работать с последней доступной версией Ext JS. Промежуточный вариант можно найти в ветке ext42 — его должно быть достаточно для данного тюториала.

                                    Насчет линков на скачивание Ext JS и иконок — полностью согласен, исправлю.

                                    Кстати, я только что вручную подправил URL, и попал напрямую на страницу для скачивания 4.1.1a: www.sencha.com/products/extjs/download/ext-js-4.1.1. Сейчас добавлю эту ссылку, если Хабр позволит.

                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                  Самое читаемое