PDA

Просмотр полной версии : custom itemEditor AdvancedDataGrid


Dukobpa3
31.12.2012, 11:41
Написал свой itemEditor для AdvancedDataGrid.

В этом эдиторе есть кнопка которая грузит файл с диска на сервер и вкручивает урл в поле данных.
Проблема в том что когда я выбираю файл, выкидывается виндовый диалог выбора файлов. ДатаГрид теряет фокус. А при потере фокуса он убивает эдитор по-умолчанию.

Так вот эту проблему я решил, уже не убивает если мне не надо его убивать. Но теперь другая хрень. ДатаГрид использует ровно столько єдиторов и рендереров сколько влазит в экран. В моем случае 20 штук.
Если таблица больше 20-и - те которые не влазят в первую страницу редактируются неадекватно.

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

Окай, сделал так, но проблема с 20-ю элементами всё-равно осталась. Видимо как-то неправильно создаю. Чего гриду не хватает при создании эдитора который не влазит в первую страницу.

Код покажу если надо. Просто я совсем не уверен что правильно делаю потому просто хочу спросить - а как надо? Мне кажется что проще будет этот участок переписать нежели исправить.

alatar
31.12.2012, 12:13
Если с эдитором, то так и надо, как в последнем варианте. Ты бы в картинках объяснил, что тебе надо и что получается.

Dukobpa3
31.12.2012, 13:04
Файл который открывает диалог - находится прямо в эдиторе. Получается что результат открытия файла у меня в эдиторе. В итоге я открываю файл провожу с ним манипуляции всё ок.

Во-первых я лочу эдитор от закрытия если диалог сейчас открыт.

private function onItemEditEnd(event:AdvancedDataGridEvent):void
{
var data:NodeModel = event.itemRenderer ? event.itemRenderer.data as NodeModel : null;

if (event.currentTarget.itemEditorInstance.wait)
{
event.preventDefault();
if (event.reason == DataGridEventReason.OTHER)// этот ризон при потере фокуса приходит.
{
_editorInstance = itemEditorInstance;
_editorPosition = editedItemPosition;
}
}
}

override public function destroyItemEditor():void
{
if (_editorInstance && _editorInstance.wait)
{
return;
}
else
{
if(itemEditorInstance) super.destroyItemEditor();
_editorInstance = null;
}
}

Потом по получении фокуса гридом обратно - удаляю старый эдитор и добавляю новый с теми же данными.
private function onFocusIn(event:FocusEvent):void
{
if (_editorPosition)
{
var pos:Object = CeaUtills.cloneObject(_editorPosition);
if(_editorInstance) createItemEditor(pos.columnIndex, pos.rowIndex);
}
}
Это работает если я умещаюсь в первую страницу прокрутки (с первого по 2-й элемент) а уже на 21-м вылетает какая-то внутрення ошибка грида. так как он запакован во внешний компонент я не вижу что там и как. Говорит что где-то там он нулл получил. А какой нулл я не знаю.

Добавлено через 1 минуту
Это мой первый проект на флексе, я вообще пур-ас3 пишу обычно. Так что не исключено что тут полная шляпа. Буду рад любым комментариям.
репо на битбакете (https://bitbucket.org/Dukobpa3/contenteditorair)

Добавлено через 5 минут
Эта схема редактирует текущую ячейку нормально. Но при переходе на другую вылетает. При условии что текущая находится вне этих 20-и строк. Ошибка где-то внутри грида в editEnd().

alatar
31.12.2012, 13:47
Это работает если я умещаюсь в первую страницу прокрутки (с первого по 2-й элемент) а уже на 21-м вылетает какая-то внутрення ошибка грида. так как он запакован во внешний компонент я не вижу что там и как. Говорит что где-то там он нулл получил. А какой нулл я не знаю.
В смысле? По стеку назад пройдись и посмотри.

Можно и без editor'a обойтись. Сделай просто ItemRenderer с кнопкой (или выглядящий как кнопка), при клике на него вызывай диалог открытия файла и посылай всплывающее событие со ссылкой на item и filereference (как пример). Или прям в рендерере и меняй данные.

Или из эдитора событие посылай и не трогай onItemEditEnd.

Не понятно зачем тебе понадобился эдитор в данном случае, если он не редактирует данные.

Dukobpa3
31.12.2012, 14:01
В смысле? По стеку назад пройдись и посмотри. Весь стек внутри грида, там нету ни одной строчки моего кода.

Не понятно зачем тебе понадобился эдитор в данном случае, если он не редактирует данные.
Ну как это не меняет, он ссылку полученную в данные сохраняет. Плюс к этой кнопке там можно этот урл вручную вбить, не выбирая файл.

alatar
31.12.2012, 14:40
Открой отдельное окно и не мучайся. ItemEditor больше подходит для инлайн редактирования.
Скорее всего ты пытаешься получить несуществующий рендерер. Увы я стек телепатически получать не умею. В каком классе, в исходниках, хоть находится приведенный код?

Dukobpa3
31.12.2012, 15:17
28910
Ну так инлайн редактирование и есть) Еще одно окно я слабо представляю куда тут прикрутить. Но могу конечно вынести кнопку куда-то нафиг в тулбар, а потом руками всё делать, данные обновлять и в таком духе.

Dukobpa3
31.12.2012, 15:20
В каком классе, в исходниках, хоть находится приведенный код?
в классе расширяющем АДГ

alatar
31.12.2012, 15:37
в классе расширяющем АДГ
Я не вижу там класса расширяющего ADG?

Добавлено через 2 минуты
Что сохраняется в editedItemPosition?

Dukobpa3
31.12.2012, 15:46
JsonTreeGrid.mxml (https://bitbucket.org/Dukobpa3/contenteditorair/src/8b8ce4e63d48e5ee426a90b05d72759c36d6da1f/src/com/earwig/contenteditor/view/components/JsonTreeGrid.mxml)

Добавлено через 46 секунд
Короче ладно, прикручу тулбар. Но вообще проблему хотелось бы решить хотя бы из-за спортивного интереса.

Добавлено через 5 минут
Что сохраняется в editedItemPosition?
Это переменная АДГ которая обновляется когда начали изменение. Тут хранится координата редактируемой ячейки.

alatar
31.12.2012, 16:38
Попробуй сделать минимальный пример с багом.

Dukobpa3
02.01.2013, 11:39
Сложно обрезать всё лишнее. По сути именно этот самый минимальный пример я и скидывал чуть выше.

Придумал как поменять логику не нарушая идею интерфейса.
28917
Вся таблица это вот такое вот дерево. Каждый узел дерева это некий NodeModel Собственно во все эдиторы и рендереры этот ноде модел попадает как data и отображается или редактируется.
Но NodeModel это базовый класс его потом расширяет еще пачка разных. ArrayNodeModel, FileNodeModel, AssetNodeModel.

Со своим уникальным функционалом каждый. Там могут чилды добавляться там не могут там с диска грузится и сохраняется там нет. Короче решил вынести вот эту вот загрузку файла и получение ссылки из эдитора в AssetNodeModel. Тогда я могу вообще не париться и кнопкой в эдиторе дергать что-то типа: data.startLoadAsset();
Потеря фокуса и восстановление эдитора уже не будет проблемой так как действия будут происходить напрямую в классе ноды, и не будет необходимости каким-то образом их из эдитора туда вставлять.

Dukobpa3
02.01.2013, 12:03
Взлетело без геморроя с таким подходом :)