Общие принципы организации GUI для редактирования модели данных
От: _hum_ Беларусь  
Дата: 06.08.13 15:01
Оценка:
Господа, пытаюсь осознать общие принципы написания GUI для ввода и редактирования модели данных. На первый взгляд кажется, что должно быть что-то типа:
1) инициация пользователем процесса ввода новых данных (соответственно, появление некоторого графического элемента, предоставляющего такой ввод — напраимер, диалогового окна);
2) ввод данных пользователем;
3) подтверждение окончания ввода.

Далее,
1) забираем информацию, введенную пользователем;
2) проверяем ее на совместимость в модели (чтобы не нарушить целостность последней);
3) если все ОК, то обновляем модель и обновляем представление, если нет, то выдаем какое-то сообщение о невозможности.

Тут вроде все ясно. Но! В большинcтве графических элементов ввода информации (текстовых полей, лист-контролов, таблиц) таких явных разделений на этапы инициации, ввода данных и подтверждения завершения ввода нет. Как быть в таких случаях с проверкой на целостность? Где об этом можно прочесть?
Re: Общие принципы организации GUI для редактирования модели данных
От: herethere  
Дата: 06.08.13 18:19
Оценка:
Здравствуйте, _hum_, Вы писали:

__>В большинcтве графических элементов ввода информации....


Боже, какая напыщенность! "Контролов" штоле??

__> ...таких явных разделений на этапы инициации, ввода данных и подтверждения завершения ввода нет.


А с чего бы им там быть?? Контрол — это просто "элемент для взаимодействия с человеком", все эти валидации/инициализации и прочее — бизнес логика, причём далеко не обязательная.

__>Как быть в таких случаях с проверкой на целостность?


Так же, как всегда: либо проверяем "на лету" (при изменении содержимого контрола), либо в конце всего ввода (если есть зависимые проперти).
Re[2]: Общие принципы организации GUI для редактирования модели данных
От: _hum_ Беларусь  
Дата: 07.08.13 13:36
Оценка:
Здравствуйте, herethere, Вы писали:

H>Здравствуйте, _hum_, Вы писали:


__>> ...таких явных разделений на этапы инициации, ввода данных и подтверждения завершения ввода нет.


H>А с чего бы им там быть?? Контрол — это просто "элемент для взаимодействия с человеком", все эти валидации/инициализации и прочее — бизнес логика, причём далеко не обязательная.


Речь шла о работе пользователя с контролом — нет явно выраженного разделения на этапы: пользователь что-то сделал, чтобы начать ввод данных, пользователь что-то сделал, чтобы подтвердить окончание ввода.

__>>Как быть в таких случаях с проверкой на целостность?


H>Так же, как всегда: либо проверяем "на лету" (при изменении содержимого контрола), либо в конце всего ввода (если есть зависимые проперти).


Гениально. Только как узнать, где "конец всего ввода"? (Вы вообще вникали в суть написанного мною или просто поприкалывались? Я об отсутствии явной выраженности этого момента как раз и говорил.)
Re: Общие принципы организации GUI для редактирования модели данных
От: maxkar  
Дата: 07.08.13 14:51
Оценка:
Здравствуйте, _hum_, Вы писали:

__>Далее,

__>1) забираем информацию, введенную пользователем;
__>2) проверяем ее на совместимость в модели (чтобы не нарушить целостность последней);
__>3) если все ОК, то обновляем модель и обновляем представление, если нет, то выдаем какое-то сообщение о невозможности.

Не обязательно. Подобная проверка может выполняться прямо в процессе ввода. Нужно смотреть на конкретные требования.

__>Тут вроде все ясно. Но! В большинcтве графических элементов ввода информации (текстовых полей, лист-контролов, таблиц) таких явных разделений на этапы инициации, ввода данных и подтверждения завершения ввода нет.


Правильно. Нет.
1. Компонент отображает только часть данных. "Текстовое поле" — это всего лишь часть сложного объекта данных. Может быть ситуация, когда нужно валидировать содерижмое нескольких полей вместе и сообщение о валидации не может быть привязано к отдельному визуальному компоненту.
2. Способов отображения невалидного состояния много. Можно отображать в самом контроле (или подсвечивать только неверную часть). Можно рядом с контролом. Можно вообще в отдельной области уведомлений (я так делал в одном приложении, в случае ошибок выводятся ошибки, в остальном — некоторая диагностика).
3. Для большинства компонентов характерно наличие невалидных данных в процессе ввода.

__>Как быть в таких случаях с проверкой на целостность?

Зависит от приложения. Вариантов масса:
1. Выполнять валидацию "на лету" и выводить нужные подсказки.
2. Выполнять валидацию только по нажатию кнопки и подсвечивать "Невалидные" поля.
3. Выполнять валидацию по клику и выводить информацию об ошибках в отдельном окне.
4. Выполнять валидацию по клику. При этом пытаться сделать автокоррекцию в окне информации об ошибках (или в основном окне). Это актуально, если выводится форма "подтверждения". Там можно вывести информацию о наличии автокоррекций и самих коррекциях. Например, можно исправить даты "начала/конца действия ограничения" если они заданы в неверном порядке.

Данные очень разные и решения нужно подбирать к конкретным вводимым данным и сценариям пользователей. И от самого приложения тоже много зависит. В веб и "толстом клиенте" могут использоваться разные подходы (из-за ограничений архитектуры или используемых библиотек).
Re[2]: Общие принципы организации GUI для редактирования модели данных
От: _hum_ Беларусь  
Дата: 07.08.13 16:24
Оценка:
Здравствуйте, maxkar, Вы писали:

M>Здравствуйте, _hum_, Вы писали:


__>>Далее,

__>>1) забираем информацию, введенную пользователем;
__>>2) проверяем ее на совместимость в модели (чтобы не нарушить целостность последней);
__>>3) если все ОК, то обновляем модель и обновляем представление, если нет, то выдаем какое-то сообщение о невозможности.

M>Не обязательно. Подобная проверка может выполняться прямо в процессе ввода. Нужно смотреть на конкретные требования.


Проверка в процессе ввода выглядит слишком вычурной.

__>>Тут вроде все ясно. Но! В большинcтве графических элементов ввода информации (текстовых полей, лист-контролов, таблиц) таких явных разделений на этапы инициации, ввода данных и подтверждения завершения ввода нет.


M>Правильно. Нет.

M> 1. Компонент отображает только часть данных. "Текстовое поле" — это всего лишь часть сложного объекта данных. Может быть ситуация, когда нужно валидировать содерижмое нескольких полей вместе и сообщение о валидации не может быть привязано к отдельному визуальному компоненту.
M> 2. Способов отображения невалидного состояния много. Можно отображать в самом контроле (или подсвечивать только неверную часть). Можно рядом с контролом. Можно вообще в отдельной области уведомлений (я так делал в одном приложении, в случае ошибок выводятся ошибки, в остальном — некоторая диагностика).
M> 3. Для большинства компонентов характерно наличие невалидных данных в процессе ввода.

Вопрос же был не в том, как именно выдавать сообщение об ошибочных данных, а в том, как узнать, что процесс ввода завершен, и можно эту проверку начинать.
И да, хоть, как вы говорите, "может быть ситуация, когда нужно валидировать содерижмое нескольких полей вместе", это ничего не меняет, так как фокус ввода всегда находится на каком-то конкретном поле, а значит, именно его данные в данный момент редактируются и ответственны за нарушение целостности — все остальные УЖЕ ВНЕСЕНЫ В МОДЕЛЬ и проблемы с нарушением целостности не представляют (а "подсветить" их при необходимости — плевое дело).

__>>Как быть в таких случаях с проверкой на целостность?

M>Зависит от приложения. Вариантов масса:
M> 1. Выполнять валидацию "на лету" и выводить нужные подсказки.

Не вариант — см. выше.

M> 2. Выполнять валидацию только по нажатию кнопки и подсвечивать "Невалидные" поля.


Какой кнопки? Такое возможно только в случае использования отдельных диалоговых окон редактирования. А если речь идет о работе с самим исходным представлением данных модели (например, с таблицей), то никаких кнопок попросту нет.

M> 3. Выполнять валидацию по клику и выводить информацию об ошибках в отдельном окне.


По какому клику? Вне зоны фокуса редактирования?

M>Данные очень разные и решения нужно подбирать к конкретным вводимым данным и сценариям пользователей. И от самого приложения тоже много зависит. В веб и "толстом клиенте" могут использоваться разные подходы (из-за ограничений архитектуры или используемых библиотек).


Это понятно, но неужели надо каждый раз изобретать велосипеды? Вроде ж какие-то концепты на эту тему типа MVC, MVP и проч. разрабатывались. Нет?


В явном виде у меня это проблема проявилась при работе с таблицами (данные моей модели представляются в виде таблицы). Если начало редактирования здесь еще явное (пользователь щелкает мышью по ячейке — на месте ячейки вставляется появляется LineEdit, позволяющий осуществлять ввод), то с его завершением полные непонятки. В большинстве случаев неявно пользователю предлагается кликнуть где-нибудь на другой ячейке ("отщелкнуть"), чтобы "подтвердить ввод" тех данных, которые он вводил. Но! Во-первых, это настолько неявно, что многие пользователи просто этого не знают, из-за чего происходят ошибки (например, не "отщелкнул" последнее введенное значение и закрыл программу). Во-вторых, поскольку обычно вид LineEdit отличается от вида ячейки только моргающим курсором, то для пользователя не очевиден момент: он при вводе значения СРАЗУ меняет это значение в модели, или это изменение происходит только после "отщелкивания"? Ну и, в-третьих, нет возможности отмены введенного значения до его подтверждения (типа функции кнопки cancel в диалоговом окне редактирования).
Из этого я сделал вывод, что такое табличное представление (такой табличный контрол) нацелен именно на синхронное изменение данных в модели:
ввод данных в представление -> синхронное изменение данных в модели

(тогда все как бы ясно, кроме момента с "отщелкиванием" — непонятно, зачем он нужен).
Но как быть, когда хочется использовать табличное представление с асинхронным изменением модели:
ввод данных в представление -> подтверждение/отмена ввода -> валидация данных -> изменение данных в модели/отказ в изменении

?
Интуитивно кажется, что в таких случаях при работе пользователя с представлением обязательно в явном виде должны выделяться три момента, о которых я ранее говорил:
1) пользовательская инициация ввода данных
2) пользовательский ввод данных
3) пользовательское подтверждения окончания ввода данных или отмены

Для таблицы это должно было бы, например, выглядеть так:
1) щелчок по ячейке — появление в области ячейки минидиалогового окошка с LineEdit и двумя миникнопками, отвечающими "ОК", "Cancel".
2) ввод текста в LineEdit
3) нажатие кнопки "ОК"/"Cancel"
При попытке щелкнуть на другую ячейку при незавершенном нажатием одной из кнопок"ОК"/"Cancel", редактирование бы запрещалось (как в модальном диалоге).
Но почему-то я таких вариантов редактирования таблиц нигде не встречал....


Грубо говоря, если бы я задался целью написать некое абстрактное архитектурное решение, то, по идее, как минимум туда должны быть включены события, отвечающие трем указанным пунктам. Но из проштудированной пока инфы я ничего подобного не нашел...Вот и весь в раздумьях, на какие принципы опираться при написании проги...
Re[2]: Общие принципы организации GUI для редактирования модели данных
От: Аноним  
Дата: 08.08.13 10:06
Оценка:
Здравствуйте, herethere, Вы писали:

__>>В большинcтве графических элементов ввода информации....


H>Боже, какая напыщенность! "Контролов" штоле??


+1. Я прямо с заголовка не понял — "редактирования модели данных" это в моем представлении типа изменение схемы БД. А принципы тогда простые: дайте юзеры две вьюхи, в одной он пусть таблички и их поля драг-н-дропит, стрелочками ссылки обозначает, главное, чтобы во второй вьюхе можно было обычным текстом (например, SQL'ем) сделать ALTER (или CREATE, что более юзабельно). Но, видимо, автор написал слово "модель" по тем же причинам, по которым контролы — графическими элементами ввода информации и речь идет... о чем угодно.
Re[3]: Общие принципы организации GUI для редактирования модели данных
От: maxkar  
Дата: 08.08.13 17:37
Оценка:
Здравствуйте, _hum_, Вы писали:

Давайте уточним, о чем мы говорим. Об "общем случае" или о какой-то конкретной ситуации. Про "общий случай" я расскажу, но ответы, скорее всего, будут совсем не те, которые вы ожидаете.

__>Вопрос же был не в том, как именно выдавать сообщение об ошибочных данных, а в том, как узнать, что процесс ввода завершен, и можно эту проверку начинать.

Какой ввод? Зачем ввод? Все очень зависит от конкретики. В некоторых случаях "можно начинать проверку" на любое редактирование. В некоторых — по смене фокуса. В некоторых — при нажатии на кнопку "сохранить" или начале любого другого действия, не связанного с редактированием (неявный commit данных). Повторю — для различных ситуаций будут различные решения.

__>И да, хоть, как вы говорите, "может быть ситуация, когда нужно валидировать содерижмое нескольких полей вместе", это ничего не меняет, так как фокус ввода всегда находится на каком-то конкретном поле, а значит, именно его данные в данный момент редактируются и ответственны за нарушение целостности — все остальные УЖЕ ВНЕСЕНЫ В МОДЕЛЬ и проблемы с нарушением целостности не представляют (а "подсветить" их при необходимости — плевое дело).


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

Пример "сочетания полей". Заказ билетов в поезде. Нужно указать дату, маршрут, номер поезда, номер вагона, номер места. Допустим, мне на определенную дату места не понравились. Я после этого изменил дату. Оказалось, что в тот день поезд короче или место занято. Вы предлагаете подсвечивать последнее поле ввода или все-таки что-то другое? Заметьте, причиной невалидности стало одно поле, но проблема будет решаться правкой других полей.

И не говорите, что "у вас не так". Сначала расскажите, какая конкретно у вас ситуация и для чего делается UI.

Еще одно замечание. О какой "модели данных" вы говорите? Есть модель UI (которая одним образом обрабатывает валидацию и "невалидная модель" — нормальное состояние). Есть бизнес-модель и модель данных, в которых уже "не допускаются" невалидные данные (невалидные — в рамках сценариев). И модификация бизнес-модели обычно привязана все-таки к какому-нибудь действию (явное сохранение и т.п.).

M>> 2. Выполнять валидацию только по нажатию кнопки и подсвечивать "Невалидные" поля.


__>Какой кнопки? Такое возможно только в случае использования отдельных диалоговых окон редактирования.

Почему? Хотя в основном — да, в окнах редактирования. Но все зависит от приложения. Точнее, от момента начала действия над данными. Вполне может быть кнопка и для сохранения всех внесенных в "таблицу"/список данных. А до этого отдельно подсвечивать невалидные и измененные строки. Или у вас "сохранение" данных автоматически на каждую правку? Это редкий сценарий. Но возможный. В этом случае проще всего обучить оператора и объяснить, что данные сохраняются "сразу после исправления". Кстати, вполне естественно будет в таком случае сохранять любое валидное состояние после редактирования. А может даже и не валидные. Например, оператор начал что-то вводить в текстовое поле и куда-то ушел. В зависимости от задачи можно "потерять" эти изменения, а можно сохранить.

__>А если речь идет о работе с самим исходным представлением данных модели (например, с таблицей), то никаких кнопок попросту нет.

Не важно, какое "исходное представление" для разработки UI! Нужно делать удобный UI. Если "исходное представление" неудобное, значит, нужно его адаптировать в нужную модель в UI. "Таблицы в виде модели предметной области" встречаются не слишком часто. А все остальное нужно подгонять под пользователя, а не под "архитектуру".

M>> 3. Выполнять валидацию по клику и выводить информацию об ошибках в отдельном окне.

__>По какому клику? Вне зоны фокуса редактирования?

По клику, который какое-то действие с данными делает. Или явно сохраняет. Если автосохранение — то при любой смене фокуса.

M>>Данные очень разные и решения нужно подбирать к конкретным вводимым данным и сценариям пользователей. И от самого приложения тоже много зависит. В веб и "толстом клиенте" могут использоваться разные подходы (из-за ограничений архитектуры или используемых библиотек).

__>Это понятно, но неужели надо каждый раз изобретать велосипеды? Вроде ж какие-то концепты на эту тему типа MVC, MVP и проч. разрабатывались. Нет?

Так у всех пользователей свои задачи. Поэтому и взаимодействие пользователя с UI в каждом случае будет свое. Конкретные подходы определяются не "общей архитектурой" а предметной областью. И решения очень чувствительны к массе условий. А какой-нибудь MVC можно использовать. В совершенно общем виде. У вас есть модель UI. Не просто "модель", а именно "модель UI", в которой отражено текущее состояние UI (в том числе — незаконченный ввод и т.п.). Из этого состояния вычисляется валидность. Могут вычисляться прочие статусы (это вот изменившаяся строчка, которая UI уже как-то выделяется). Но это совершенно общие вещи и правильно их использовать в каждом конкретном случае — задача программиста.


__>В явном виде у меня это проблема проявилась при работе с таблицами (данные моей модели представляются в виде таблицы).

Так может это проблемы таблиц? Может, нужно списом с "плашками" определного формата?

__>Если начало редактирования здесь еще явное (пользователь щелкает мышью по ячейке — на месте ячейки вставляется появляется LineEdit, позволяющий осуществлять ввод), то с его завершением полные непонятки. В большинстве случаев неявно пользователю предлагается кликнуть где-нибудь на другой ячейке ("отщелкнуть"), чтобы "подтвердить ввод" тех данных, которые он вводил. Но! Во-первых, это настолько неявно, что многие пользователи просто этого не знают, из-за чего происходят ошибки (например, не "отщелкнул" последнее введенное значение и закрыл программу).


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

__>Во-вторых, поскольку обычно вид LineEdit отличается от вида ячейки только моргающим курсором, то для пользователя не очевиден момент: он при вводе значения СРАЗУ меняет это значение в модели, или это изменение происходит только после "отщелкивания"?

Ну сделайте явно заметный вид. На HTML я баловался и делал "сильный" фокус. Редактируемая область (примерный аналог вашей строки) выделяется рамкой. Все остальное немного засеривается. Выход делается явным подтверждением.

__>Ну и, в-третьих, нет возможности отмены введенного значения до его подтверждения (типа функции кнопки cancel в диалоговом окне редактирования).

Во-первых, у вас должны работать стандартные шоткаты (Ctrl-Z). Это уже позволяет отменять операции. Во-вторых, у вас там autosave? Вы же сами себя ограничили, что у вас нет явного "сохранения" (и откатываться некуда). Явная кнопка "сохранить" решает много проблем. С подсвечиванием изменений — еще больше. С возможностью отменить/посмотреть изменение в конкретной ячейке — еще больше. Это все нужно делать ручками. Можно для организации сделать и набор контролов, и набор интерфейсов моделей, если задачи частые. Да, нужно ручками работать. Но никаких космических технологий тут нет

__>Из этого я сделал вывод, что такое табличное представление (такой табличный контрол) нацелен именно на синхронное изменение данных в модели:

__> Но как быть, когда хочется использовать табличное представление с асинхронным изменением модели:

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

__>Для таблицы это должно было бы, например, выглядеть так:

__>1) щелчок по ячейке — появление в области ячейки минидиалогового окошка с LineEdit и двумя миникнопками, отвечающими "ОК", "Cancel".
__>2) ввод текста в LineEdit
__>3) нажатие кнопки "ОК"/"Cancel"
__>При попытке щелкнуть на другую ячейку при незавершенном нажатием одной из кнопок"ОК"/"Cancel", редактирование бы запрещалось (как в модальном диалоге).
__>Но почему-то я таких вариантов редактирования таблиц нигде не встречал....
Потому что это издевательство над пользователем. Пользователь же работает не с ячеками. Он с таблицей работает! И "моделью" в этом случае для пользователя является вся таблица, она неделима. То, что у вас там в UI по модели для каждого поля, никого не интересует.


__>Грубо говоря, если бы я задался целью написать некое абстрактное архитектурное решение, то, по идее, как минимум туда должны быть включены события, отвечающие трем указанным пунктам. Но из проштудированной пока инфы я ничего подобного не нашел...Вот и весь в раздумьях, на какие принципы опираться при написании проги...


Так не является "отдельное поле" моделью с точки зрения пользователя. И "единица редактирования" — это весь ваш экран ввода данных обычно. Именно что не отдельной ячекий. Напишите свои контролы в конце концов. У меня текстовые поля на каждый ввод модель меняют (UI-модель, сохранение — это отдельное действие для всего набора данных). Да, именно любое действие приводит к изменению состояния UI. Как моделировать "пользователь закончил ввод" — это отдельный сложный вопрос. И ответ на него тоже зависит от конкретных сценариев, под которые разрабатывается интерфейс. Общих решений здесь нет. Можно ведь и модальное поле с кнопками "ok/cancel" сделать. Мы где-то на одно текстовое поле делали еще небольшой диалог редактирования (потому что так оказывалось проще).

Общий подход в разработке UI — начать с анализа сценариев пользователей. И уже под это делать архитектурное решение. Общим оно не получится. Слишком требования разные. А вот для определенной области какое-то общее решение может оказаться приемлемым.
Re: Общие принципы организации GUI для редактирования модели данных
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.08.13 08:45
Оценка: 3 (1) +1
Здравствуйте, _hum_, Вы писали:

__>Господа, пытаюсь осознать общие принципы написания GUI для ввода и редактирования модели данных. На первый взгляд кажется, что должно быть что-то типа:

__>1) инициация пользователем процесса ввода новых данных (соответственно, появление некоторого графического элемента, предоставляющего такой ввод — напраимер, диалогового окна);
__>2) ввод данных пользователем;
__>3) подтверждение окончания ввода.

__>Далее,

__>1) забираем информацию, введенную пользователем;
__>2) проверяем ее на совместимость в модели (чтобы не нарушить целостность последней);
__>3) если все ОК, то обновляем модель и обновляем представление, если нет, то выдаем какое-то сообщение о невозможности.

__>Тут вроде все ясно. Но! В большинcтве графических элементов ввода информации (текстовых полей, лист-контролов, таблиц) таких явных разделений на этапы инициации, ввода данных и подтверждения завершения ввода нет. Как быть в таких случаях с проверкой на целостность? Где об этом можно прочесть?


Коротко о главном: нужно разрешать "любой" ввод и сохранять всё.
Запрещать нужно переходы состояний в workflow. Например, нельзя перевести заказ в состояние "отправлен", если в нём не хватает каких-то данных или что-то введено неправильно. Нельзя выполнить "поиск маршрутов", если дата "туда" позже даты "обратно".

Считайте "диагностические" элементы частью модели данных, которые вычисляются автоматически по некоторым формулам. Например, элемент "корректность диапазона дат" будет содержать {true, "Ok"} если .dateTo <= .dateBack, и соответствующим образом отображаться (или неотображаться) в UI. В противном случае он должен содержать что-то типа {false, "Дата обратного вылета должна быть позже даты прямого вылета"}.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Общие принципы организации GUI для редактирования модели данных
От: Visor2004  
Дата: 28.08.13 11:06
Оценка: +1 :)
Здравствуйте, _hum_, Вы писали:

__>Гениально. Только как узнать, где "конец всего ввода"? (Вы вообще вникали в суть написанного мною или просто поприкалывались? Я об отсутствии явной выраженности этого момента как раз и говорил.)

там где пользователь нажимает OK/Save/Apply
Помните!!! ваш говнокод кому-то предстоит разгребать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.