element.args().caller() - хорошая мысль. но очень грубо
element.args().lookup*() - прекрасно. спасибо.
но я пошел уже другим путем и отрефакторил.
принцип по которому я пошел:
- я не добавляю свой датасорса в форму. что делает модификацию сильно легче - один edit-метод на форме + 1 контрол на форме
- я использую тот факт, что после super() в инициализации есть только Query, а QueryRun == null
- я работаю только с queryrun().query(), использую research(). И никогда сам не вызываю executeQuery(), который пересоздает queryRun из АОТ
- в частности, я добавляю свой датасорс только после того, как пользователь выбрал какой-то пункт в переключателе
- я отрефакторил код и трактую отсутствие моего датасорса как вполне валидное состояние "Все записи"
получился вот такой код:
X++:
protected static MdmViewMode get(FormDataSource fdsMain, TableId shadowTableId)
{
MdmViewMode ret;
EnumId enumId = enumnum(MdmType);
QueryRun qr = fdsMain ? fdsMain.queryRun() : null;
QueryBuildDataSource qbds = qr ? qr.query().dataSourceTable(shadowTableId, 1) : null;
SysDictField field = qbds ? SysDictTable::fieldWithEnum(qbds.table(), enumId) : null;
QueryBuildRange qbr = field ? qbds.findRange(field.id()) : null;
str rangeValue = qbr ? qbr.value() : '';
;
if( !qbds || !qbds.enabled() )
{
ret = MdmViewMode::All;
}
else if( qbds && qbds.joinMode() == JoinMode::NoExistsJoin && rangeValue == SysQuery::value(MdmEnumViewMode::completed()) )
{
ret = MdmViewMode::InProcess;
}
else if( qbds && qbds.joinMode() == JoinMode::NoExistsJoin && rangeValue == SysQuery::value(MdmType::StopProcessing) )
{
ret = MdmViewMode::Active;
}
else if( qbds && qbds.joinMode() == JoinMode::ExistsJoin && rangeValue == SysQuery::value(MdmType::StopProcessing) )
{
ret = MdmViewMode::Stopped;
}
else if( qbds && qbds.joinMode() == JoinMode::ExistsJoin && rangeValue == SysQuery::value(MdmType::Error) )
{
ret = MdmViewMode::Error;
}
else
{
ret = MdmViewMode::UserDefined;
}
return ret;
}
X++:
// предполагаем, что в запросе только один range по полю mdmType
protected static boolean set(
FormDataSource fdsMain,
TableId shadowTableId,
MdmViewMode viewMode)
{
EnumId enumId = enumnum(MdmType);
QueryRun qr = fdsMain ? fdsMain.queryRun() : null;
QueryBuildDataSource qbds = qr ? SysQuery::findOrCreateDataSource(qr.query(), shadowTableId, fdsMain.table()) : null;
SysDictField field = qbds ? SysDictTable::fieldWithEnum(qbds.table(), enumId) : null;
str rangeValue;
;
if( qbds && field )
{
startLengthyOperation();
switch( viewMode )
{
case MdmViewMode::UserDefined:
qbds.enabled(true);
qbds.relations(true);
qbds.joinMode(JoinMode::InnerJoin);
rangeValue = SysQuery::valueUnlimited();
break;
case MdmViewMode::All:
qbds.enabled(false);
qbds.relations(true);
qbds.joinMode(JoinMode::ExistsJoin);
rangeValue = SysQuery::valueUnlimited();
break;
case MdmViewMode::InProcess:
qbds.enabled(true);
qbds.relations(true);
qbds.joinMode(JoinMode::NoExistsJoin);
rangeValue = SysQuery::value(MdmEnumViewMode::completed());
break;
case MdmViewMode::Active:
qbds.enabled(true);
qbds.relations(true);
qbds.joinMode(JoinMode::NoExistsJoin);
rangeValue = SysQuery::value(MdmType::StopProcessing);
break;
case MdmViewMode::Stopped:
qbds.enabled(true);
qbds.relations(true);
qbds.joinMode(JoinMode::ExistsJoin);
rangeValue = SysQuery::value(MdmType::StopProcessing);
break;
case MdmViewMode::Error:
qbds.enabled(true);
qbds.relations(true);
qbds.joinMode(JoinMode::ExistsJoin);
rangeValue = SysQuery::value(MdmType::Error);
break;
default:
throw error(Error::unsupportedEnum(funcname(), viewMode));
}
qbds.fetchMode(QueryFetchMode::One2One);
qbds.firstOnly(true);
SysQuery::findOrCreateRange(qbds, field.id()).value(rangeValue);
fdsMain.research();
endLengthyOperation();
return true;
}
return false;
}
таким образом я совсем не вмешиваюсь в работу формы до тех пор, пока пользователь не жамкнет переключатель. после того, как жамкнет, в queryrun формы будет добавлен датасорс.
до жамка:
после жамка:
спасибо за советы и помощь.