Как стать автором
Обновить

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

никаких аналогов setBaseParam() или load(params) больше не предоставляется.

Параметры задаются:
store.load({
    params: {
        dynamicParam_1: 'myValue_1',
        dynamicParam_2: 'myValue_2'
    }
})

Так же можно указать базовые параметры для прокcи:
store.getProxy().extraParams = {
    dynamicParam_1: 'myValue_1',
    dynamicParam_2: 'myValue_2'
};

store.load();

Но мне кажется, что этот вариант не столь красивый как фильтры.
Через прокси — это понятно. А вот первый вариант интересен, спасибо.
Так вобщем никто не мешает переопределить Storem что бы setBaseParam() изменял прокси. Ну если очень лень менять код везде.
Личные предпочтения :)
Если это принципиально — могу перенести.
Мне кажется extjs — очень интересная тема, которой необходимы русскоязычные тексты (ведь их мало), а в профильном блоге 7 постов за полгода, при том, что подписчиков не намного меньше блога javascript.
Думаю стоит развивать профильный, наполняя его. Плюс полезная инфа, вроде этого поста будет в одном месте.
Перенес в указанный вами блог. Надеюсь, топик здесь будет полезным.
А почему у вас методы toggleHelp и menuRendered находятся в контроллере, если при архитектуре MVC они должны находиться в модели?
По поводу AJAX: на мой взгляд, проблема не в «в ExtJS4 отсутствует простой случай Writer'а, который отправляет объект как множество HTTP параметров «ключ-значение»», а в том, что в классе Ext.data.Connection в методе setOptions метод Ext.Object.toQueryString() употребляется без флага, который разрешает рекурсивное преобразование. Собственно перегрузкой этого класса я и решил проблему с объектами в запросе.
1. А почему вы думаете, что бизнес-логика приложения должна находиться в модели?
2. Логикой сериализации параметров запроса занимается Writer. Поэтому естественнее определить эту логику на этом уровне. Разумеется, это не единственно возможное решение.
1. Это входит в формулировку архитектурной схемы MVC: Model in MVC pattern. Бизнес-логика в контроллере считается основной ошибкой при использовании MVC: Fat Stupid Ugly Controllers. Если следовать схеме MVC до конца, то я могу ошибаться, ведь если методы toggleHelp и menuRendered изменяют не состояние модели, а представление, то грамотнее расположить их именно в нем.
2. Разумеется, просто в случае моего приложения ошибку проще было исправить на самом низком уровне, так как объекты я использую практически во всех запросах, в том числе и совершенных с помощью Ext.Ajax.
Видимо, в теории MVC вы разбираетесь лучше меня :)
Правда, из этого следует, что аналогичную ошибку совершают и сами архитекторы из Sencha. Откровенно говоря, MVC в понимании Sencha — это не совсем то, под чем обычно оно понимается. В архитектуре там очень много намешано (MVC, Active Record, запчасти от ORM и т.п.), и нужно ли все это на клиенте — большой вопрос.
Учитывая, что схема MVC разрабатывалась именно для GUI приложений, то нужно :) Тем более, что ExtJS позволяет абстрагироваться от сервера, HTML (если не нужно писать кастомные view) и, в какой-то степени, от JavaScript, предоставляя неплохой инструментарий из методов ядра и системы классов.
Несмотря на статус релиза 4-я версия фрэймворка по количеству (и качеству) багов — ранняя бета :(
Стоит копнуть чуть глубже примеров, как вылазят баги и недоработки.
С другой стороны, лучше ExtJs пока ничего нет :)

Ситуация в том, что почти что каждая новая версия (минорная или мажорная) — это новый букет неизвестных багов и подводных камней. Так, на версии 4.0.2a встречались проблемы с IE8 и заданием стилей через конфигурационный объект. Не знаю, воспроизведется ли проблема на более свежих версиях.
Но выбирать тут не приходиться.
Баг со скроллером тянется ещё с первых беток.
Суть: полоса прокрутки в экстовских гридах не нативная от браузера, а отдельный контрол (тоже нативный, но относящийхся к другому div-у), который почти всегда работает некорректно, а иногда вовсе отваливается, причём «иногда» в некоторых конфигурациях параметров — это 100%.
Баг проявляется даже в примере: cdn.sencha.io/ext-4.0.7-gpl/examples/grid/infinite-scroll.html
Проскрольте колесом мышки вниз и сразу вверх. С вероятностью 99% вам не удастся вернуться к первому элементу.
После нескольких загрузок (поиск, например, в примере этого нет) скроллер отвалится совсем. Т.е. он будет виден, будет двигаться, но содержимое грида скроллиться не будет.
Можно по таймеру раз в минуту менять высоту грида +1, -1 пиксель, тогда скроллер подцепляется.
Можно грязными хаками обойти этот баг, например, перед загрузкой очищать грид, ставить скроллер на самый верх, реинициализировать его, вызывать store.guaranteeRange() геренируя ненужный трафик и т.п. и т.д. — а потом вдруг окажется, что и это не помогает в некоторых случаях :)
лучший вариант — отказаться вообще от infinity-скрола. В целом вся реализация и скрола и prefetch данных в сторе сделана через отдельный огород, который слабо связан как со стором в целом так и с гридами и скроллом в частности. К примеру основной контейнер данных в сторе — data при использовании prefetch в сторе наполняется не самим стором, а скроллером, что вообще за рамками понимания.
Увы, есть over 9000 строк с данными, которые так удобно просматривать крутя колёсико на мышке.
Сначала всё хорошо — берём пример, подставляем свои данные, и всё работает.

Потом нужно сделать форму поиска и сортировку на стороне сервера — этого в примерах с пагинатором нет :)
Сперва я вставлял параметры для описка в beforeLoad, потом методом тыка нашёл секретную переменную extraParams у proxy — в неё можно засунуть параметры поиска, чтобы они не сбрасывались при скроллинге, сортировке и переходе к следующей странице.

Потом данные нужно редактировать — это делается без проблем.
Но отредактированные данные надо сохранять. У стора есть метод sync() — он работает.
Сохранять нужно по нажатию на кнопку «Сохранить» — без проблем.
Но пользователя нужно предупреждать о потере несохранённых данных, если он, к примеру, изменил пару строк, забыл сохранить и полез искать что-то другое.
Это легко перехватывается в beforeLoad — опрашиваем стор, есть ли у него несохранённые данные, потом пугаем пользователя.

Потом вдруг оказывается, что при скроллинге и сортировке beforeLoad опрашивается как-то и не всегда, а если и опрашивается, то всё равно может быть поздно и данные уже потеряны :)
К тому же, может так оказаться, что пользователь испугался потери несохранённых данных при скроллинге и отменил загрузку (в beforeLoad return false), тогда данные на первой странице отсортированы по имени, а на второй — уже по дате.

А потом вдруг вылезает то, что вы написали про prefetch — на этом я не выдержал, не найдя как перехватывать и отменять, забил и сделал автоматическое сохранение сразу после внесения изменений (autoSync:true).

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

во-первых pagination никто не отменял, во-вторых в любом случае, когда over 9000, тупо отображать их нефильтрованным списком даже с фитчей infinity-scroll весьма неудобно. Пользователю всегда нужны конкретные данные, а не список в 9к строк. Т.е. нужна адекватная фильтрация + постраничная загрузка. И опять же infinity-scroll содержит очень много неочевидных косяков и с каждым апдейтом фреймворка код, связанный с этим функционалом меняется, что приводит еще к более неочевидным косякам.
Ну на фильтр вся надежда, но стартовый экран — список из полутора тысяч строк, из которых пятьдесят — в браузере, а остальные подтягиваются по мере листания.

У обычной pagination проблемы те же, насколько я понимаю — неочевидная загрузка при сортировке, которую хотя и можно отменить, но параметры сортировки придётся править при отмене вручную. Поэтому пока для меня лучший вариант — автоматическое сохранение.

>>И опять же infinity-scroll содержит очень много неочевидных косяков и с каждым апдейтом фреймворка код, связанный с этим функционалом меняется, что приводит еще к более неочевидным косякам.
Это да. Из последнего, что запомнилось — в 4.1 они убрали метод getVerticalScroller() у грида, и сделали ещё какие-то несовместимые с жизнью изменения.
Зато скорость рендеринга повысили, как и обещали. У того, что всё таки отрендерилось, а не вывалилось с ошибкой — даже в их собственных примерах firebug отлавливал исключения :)

У меня в коде уже куча грязных хаков против их багов.
Вот смотрю я на все это (происходящее с ExtJS) и думаю: а стоит ли планировать перевод своего приложения на 4-ю версию, или все же отказаться от него вовсе и [найти что-то другое || написать что-то свое]… Даже не знаю, что в данном случае будет большим злом.

Пока, судя по всему, надо тупо ждать и смотреть, что же будет дальше :)
Как раз завтра планирую начать новое приложение на 4й версии, хотя есть возможность скопировать похожее на третей версии. Что выйдет пока не знаю, но надеюсь на удачный исход.
Ну на самом деле не все так страшно с ExtJS.
Для меня основной загвоздкой в вопросе портирования было отсутствие по факту модульной структуры приложения. Это удалось решить собственной реализацией вложенных MVC (вариация на тему HMVC), так удалось «размыть» реальную границу между старым и новым подходом в разработке приложения и сохранить динамическую структуру.

Но с другой стороны, в моем случае вопрос «на чем писать» не стоял.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории