Комментарии 25
По поводу лишних запятых. Правильные IDE (например у меня SpKet) сразу показывают такие ошибки. Да и JSLint помогает.
А за статьи спасибо, я, хоть уже и почти год ExtJS использую, пару новых полезных моментов узнал. Например про плагины, это по сути ведь паттерн декоратор получается?
Да, именно он. Там сплошные паттерны. Взять те же createInterceptor и createSequence, например.
А почему в коде
#, tbar: new Ext.Toolbar({
#, items: [{
#, text: «Add»
#, handler: this.entityAdd.createDelegate(this) // [3]
# },{
используется createDelegate(this) а не
#{
#, text: «Add»
#, handler: this.entityAdd // [3]
#, scope: this // < —
# }
Ничто не мешает использовать scope в конфигурации, если вам дополнительная гибкость не нужна. Дело в том, что createDelegate позволяет передавать в функцию дополнительные аргументы (это его огромнейшее преимущество).
Что-то я не догоняю.
А чем отличается запись
Ext.apply(this, {
   store: new Ext.data.JsonStore({/* Настройки хранилища */}); // [1]
});
от
this.store = new Ext.data.JsonStore({/* Настройки хранилища */});
?
Если ни чем, то по-моему однострочный вариант лучше.

И по поводу
При проектировании больших приложений привяжитесь к одной версии Ext и не меняйте её.
Я бы такого не советовал, так как на моем опыте переход с ветки 2.1 на 3.0 прошел почти безболезненно. Были парочка багов, я даже писал на форум про баги. В версии 3.0.1 их уже не было.
Но я бы не советовал «хачить» Extjs. То-есть не использовать свойства, которых нет в API, что б не получить неработающий код после обновлений.
Ну и тесты использовать нужно в больших проектах.

Но вообще статья доходчивая, спасибо! Не знал, что плагины можно регить ( Ext.preg ).
Да, можно вообще Ext.apply не использовать, так как в данном контексте он ничего не даёт.

Касательно привязки привязки к версии — у нас всего лишь был разный опыт «общения» с фреймворком. У меня при апдейтах из репозитория, равно как и при официальном апдейте с 3.0.0 на 3.0.1 лезли пренеприятнейшие, непонятные ошибки. А я недокументированных возможностей, помимо конфигураций графиков, нигде не использовал (графики слабо документированы, приходилось смотреть их исходные коды). Таким образом, если есть даже малейший шанс заполучить хотя бы одну из тех ошибок, связанных с обратной совместимостью — лучше этого избежать. Я трижды откатывался на прежнюю версию, прежде чем окончательно забросить попытки мигрировать в середине проекта на пропатченый Екст. И теперь жалею, что вообще пытался. Если перефразировать Кнута: корень всех бед в миграции без веских причин.

И спасибо за ваш вердикт касательно статьи :)
А как же баги? В 3.0.0 я уже наткнулся на два крайне критичных для меня бага (не работал скроллинг в каком-то виджете и ещё что-то), пришлось перелазить. Плюс если не пользоваться хаками, то вполне всё перетаскиваемо (правда, не пользоваться хаками невозможно :( ).
Смотря что вы подразумеваете под хаками. Баги в 3ей ветке, конечно, есть, но я ещё не сталкивался с критическими. Разве что в релиз кандидате, где просто не работал аккордеон в ie
Ну вот типичный хак. Нужно выровнять по вертикали размер элемента формы, то есть чтобы HtmlEditor (например) укладывался в остаток вертикального пространства окна. Используем anchor, всё хоккей. Но как только динамически скрываем-удаляем другой элемент (тоже хаком, ибо метод hide() работает совершенно парадоксально), получаем пустое место, ибо размер HtmlEditor'а не изменился. А динамически менять anchor нельзя без хака.

Или вот как поменять url у объекта Store? Хаком. А потом оказывается, что если к элементу прикручен пейджинг, то при пролистываении/обновлении всё равно открывается старый урл. Опять хак.
Я вам не подскажу на счёт выравнивания эдитора, но подскажу, как справиться с динамической сменой url в Store.

Copy Source | Copy HTML
  1. var store = new Ext.data.JsonStore({
  2. remoteSort: true
  3. , reader: new Ext.data.JsonReader()
  4. , proxy: new Ext.data.HttpProxy({
  5. api : {
  6. read : {
  7. url : "/someurl1"
  8. , method: "GET"
  9. }
  10. }
  11. })
  12. /* Другие настройки */
  13. });
  14. store.proxy.setApi(Ext.data.Api.actions.read, {method: "GET", url: "/someurl2"});
Спасибо, так правильнее, я же выловил отладчиком проблему и сделал примерно так:

mp.LList.store.proxy.api.read.url = url;
А ну самое главное забыл. Хаки — это когда ковыряешься в исходниках Ext и потом дёргаешь приватные функции из своего кода, ибо по-другому никак. Или долго и упорно ковыряешься в отладчике, вылавливая странное поведение, чтобы потом хаком это поведение поправить.
В этом случае нужно создавать свои компоненты на основе существующих, где и дописывать нужное вам поведение. Уж не знаю считать ли это хаком или просто наследованием :)
Дергать приватные функции вне методов компонента конечно не надо. А странное поведение не всегда является багом, часто это фича ;)
Тогда придётся дёргать приватные методы из отнаследованного класса. Другого пути нет. В Ext вообще слишком много шаманства, уж очень сложный продукт.

Кстати, вот на днях в интернетах появилась книга «Ext 3.0 Cookbook», весьма достойное чтиво.
Ext не безгрешен. Об этом говорят их сабмиты в свн. А хакать всё-таки приходится. Иногда (я описал случай в статье) это очень даже быстрый способ реализации той или иной функциональности, так что лучше предусмотреть возможность хака при проектировании. Есть альтернативный вариант — писать в сапорт. Они оперативно фиксят баги. В течении недели, если баг достаточно критичен. Но по моему опыту, во-первых, неделя — это очень долгий срок почти для любого проекта и, во-вторых, это означает что вы будете регулярно переходить с версии на версию. А это, опять же, огромный риск.
Да, соглашусь, приходится. Но даже подобное можно сделать красиво. Так, чтоб самого не воротило (а то и чтоб гордиться можно было). А это очень важно.
А я по другому описываю построение своих мета обьектов. Вместо наследования/расширения всего и вся, я строю функцию которая возвращает мне метаобьект/апи для работы с ним, а также настраивает взаимосвязи между внутренними базисными кирпичами.

MyProject.widgets.ProductsGrid = function(config) {

var me = {};

me.observer = new Ext.util.Observable;
me.observer.addEvents({
«addproduct»: true
});

me.store = new Ext.data.JsonStore({...})
me.grid = new Ext.grid({
store: me.store,
region: Ext.value(config.region, «center»)

})

me.addProduct = function(product) {
me.store.add(product);
me.observer.fireEvent(«addproduct», product);
}

return me;

}

Такой подход мне позволяет:
1. Отделить апи конкретного виджета с конкретным функционалом от внутренностей extjs.
2. С другой стороны, я могу грид или панели интегрировать и настраивать туда, куда захочу, через геттеры типа getGridPanel и config параметры.

Таким методом я написал для своего проекта код который позволяет мне создать динамически грид:
1. Обычный или Иерархический (maximgb treegrid), причем если я передаю параметр иерархический, то датастор уже автоматически содержит в себе описание необходимых для иерархии полей.
2. С плагином поиска, фильтрации колонок, с автоподсветкой результатов поиска
3. При дополнительных параметрах грид можно пересортировывать, через кнопки в тулбаре или драг-н-дроп.
4. Грид знает как взаимодействовать с соседским гридом, для переноса данных из одного списка в другой.
И т.д.

Конечно многое пришлось в самом ехт патчить ручками, сам до сих пор на 2.3.0 (в целом доволен) и пока не вижу возможностей и веских причин для миграции.
Скажите, а какой подход вы используете для локализации приложения (если вообще используете)?
Собственно подход к локализации в ExtJS уже представлен. Смотрите файлы в source/locale в дистрибутиве ExtJS. Подобный подход + текстовые константы вполне решают проблему локализации.
Я уже перекопал половину сорсов экста, так что про этот подход я в курсе. Я думал, что может вы предложите что-то более оригинальное, ибо не всегда хочется наследоваться от компонентов, вполне достаточно просто составить конфиг и скормить его кому нужно. А здесь уже подход, который используется в эксте, не подходит.

К сожалению, если необходимо избежать перезагрузки приложения, приходится использовать предложенный разработчиками Ext'а стандартный метод локализации с перегрузкой объектов. Это очень неудобный метод, но о лучшем я ничего не знаю. Было бы замечательно, если бы кто-то написал статью на эту тему, так как предложенный метод локализации достаточно сложен.
а как осуществляется уничтожение объекта в фреймворке? можна ли его удалить програмно, когда объект считается удаленным? можно ли как-то контролировать занимаемую память?
спасибо.
Обычно фреймворк сам регулирует жизненный цикл объектов, но в некоторых случаях необходимо самому их уничтожать. Делается это методом destroy, который определён в Ext.Component (базовый класс для всех виджетов). При этом можно отлавливать события элементов beforedestroy и destroy. Объект считается удалённым, если его свойство isDestroyed вернёт true.
НЛО прилетело и опубликовало эту надпись здесь
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.