Обновление детали по закрытии его карточки редактирования

Данные в детали изменяются не только посредством карточки редактирования, поэтому по завершении редактирования и нажатии кнопки ОК мы не видим изменений, пока деталь не обновить. Окно редактирования унаследовано от wnd_BaseDBEdit, подскажите как правильно обновить делать в данном случае.

(кнопку ОК в окне редактирования не трогал, пробовал найти решения в постах но пока безуспешно)

из последних идей нашел в постах:

function wnd_...GridAreaOnNotify(ScriptableService, Sender, Message, Data) {
        if ((Message == MSG_OK) &&
            (Sender.Name = Self.Attributes('EditWindowUSI'))) {
            var WorkspaceWindow = Self.Attributes('WorkspaceWindow');
            WorkspaceWindow.Notify(Self, MSG_REFRESHDETAIL, System.EmptyValue);
        };
        wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data);
}

но не знаю как воспользоваться правильно в моем случае

Нравится

15 комментариев

В Вашем случае function wnd_...GridAreaOnNotify - это функция OnNotify для сервиса окна реестра того раздела, детали которого Вы хотите обновлять по закрытию карточки редактирования. Указанный код проверяет, было ли сообщение о закрытии, действительно ли его послала карточка редактирования, а затем посылает разделу сообщение об обновлении деталей.

отладчик показал:
ScriptableService = wnd_SubContactPeriodsGridArea
Sender = wnd_SubContactPeriodsEdit
Message = MSG_OK
Data = undefined
Self= "wnd_SubContactPeriodsGridArea"

далее по условию должно быть
var WorkspaceWindow = Self.Attributes('WorkspaceWindow');
после этого шага WorkspaceWindow = null, ошибка видимо здесь, почему null?

Это созданный Вами раздел? Обычно в скрипте раздела в функции инициализации окну реестра в атрибут WorkspaceWindow записывается раздел. Если такого не происходит, то Вам нужно в скрипте раздела в функции Initialize (если нет такой, то на OnPrepare) присвоить атрибут таким образом:

SetAttribute(wndGridArea.Window, 'WorkspaceWindow', Self);

тут wndGridArea - это контейнер (создан в окне раздела), который содержит окно реестра.

wnd_SubContactPeriodsGridArea созданный мной раздел

выдержки кода из wnd_SubContactPeriodsGridAreaScript:

function Initialize(Window) {
    SetAttribute(Window, 'WorkspaceWindow', Self); <- добавил по вашему совету
    SetAttribute(Window, 'EditWindowUSI', 'wnd_SubContactPeriodsEdit');
    SetAttribute(Window, 'ParentItemFieldName', 'ContactID'); // id of main grid
    SubContactPeriodsGridArea.DatasetUSI = GetAttribute(Window, 'DatasetUSI');
    SubContactPeriodsGridArea.WorkspaceDataset = GetAttribute(Window, 'WorkspaceDataset'); 
}
...
function wnd_SubContactPeriodsGridAreaOnNotify(ScriptableService, Sender, Message, Data) {
    if ((Message == MSG_OK) && (Sender.Name = Self.Attributes('EditWindowUSI'))) {
        var WorkspaceWindow = Self.Attributes('WorkspaceWindow');
        WorkspaceWindow.Notify(Self, MSG_REFRESHDETAIL, System.EmptyValue);
    };
    wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data);
}

не работает :(
В BeforePost для изменения данных, помимо основного датасета детали я использую динамически созданный. Изменения, произведенные в нем всеравно отображаются после обновления руками (как и было)

Нужно же не
SetAttribute(Window, 'WorkspaceWindow', Self)
а
SetAttribute(wndGridArea.Window, 'WorkspaceWindow', Self);
Вы сейчас в атрибуты окна раздела пишете, а не в атрибуты окна грида!
Перейдите в окно раздела, посмотрите, как у Вас называется контейнер окна, содержащий грид.

в сервисе wnd_ContactWorkspace деталь выглядит так:

pcDetails - вкладки деталей
 pgSubContactPeriodsDetail - вкладка моей детали
  fmSubContactPeriodsDetailWindow - фрейм на вкладке моей детали
   wndSubContactPeriodsDetail - контейнер для окна раздела моей детали
 
wnd_SubContactPeriodsGridArea - окно раздела моей детали

было так: SetAttribute(Window, 'WorkspaceWindow', Self);
в функцию подается Window = wnd_SubContactPeriodsGridArea

Что вы подразумеваете под окном грида?
wnd_BaseGridArea?
где взять wndGridArea и зачем брать если он подается.

Я имел ввиду, что Вам нужно внести изменения в функцию инициализации скрипта Вашего раздела, а не в скриптw nd_SubContactPeriodsGridAreaScript.
Действительно, в последний приходит окно реестра (он же, грид) детали. Но Вам нужно заполнить атрибут WorkspaceWindow именно разделом, поэтому нужно именно в функции инициализации в скрипте раздела прописать строчку

SetAttribute(wndSubContactPeriodsDetail.Window, 'WorkspaceWindow', Self);

Здесь я уже поставил контейнер для Вашего случая.

раздел - контакты, => инициализация раздела происходит здесь:

// ----------------------------------------------------------------------------
// scr_ContactsGridArea
// ----------------------------------------------------------------------------
var Contacts = new Object();
 
function Initialize(Window) {
	debugger; <- в эту точку система не приходит вообще
	SetAttribute(wndSubContactPeriodsDetail.Window, 'WorkspaceWindow', Self);
...

Эта функция должна вызываться из обработчика OnPrepare. Проверьте функцию wnd_ContactsWorkspaceOnPrepare, есть ли там вызов Initialize? Обязательно должен быть этот вызов и возможно еще что-нибудь (не обязательно) для дополнительной функциональности. Проверил у себя -- инициализация проходит, как положено, при переходе на раздел, т.е. при отработке OnPrepare окна раздела.

исправил ошибки с функцией инициализации, параметр передался

function wnd_SubContactPeriodsGridAreaOnNotify(ScriptableService, Sender, Message, Data) {
debugger;
    if ((Message == MSG_OK) && (Sender.Name == Self.Attributes('EditWindowUSI'))) {
        var WorkspaceWindow = Self.Attributes('WorkspaceWindow');
        WorkspaceWindow.Notify(Self, MSG_REFRESHDETAIL, System.EmptyValue);
    };
    wnd_BaseGridAreaOnNotify(ScriptableService, Sender, Message, Data);
}

По приходу сообщения MSG_OK, WorkspaceWindow принимает wnd_ContactsWorkspace.

Деталь не обновилась.

Хорошо, теперь проверьте обработчик OnNotify скрипта раздела (scr_ContactsWorkspace.wnd_ContactsWorkspaceOnNotify), там должен быть (хотя у Вас наверное нет, так как не обновляет) фрагмент кода

	if (Message == 'MSG_REFRESHDETAIL') {
		RefreshDetails();
	}

Действительно, такого фрагмента не было, попробовал добавить фрагмент в самое начало функции, деталь не обновилась.

Отрабатывает ли при этом функция RefreshDetails? Т.е. выполняется ли условие, переходит ли на ее выполнение? Если да, то очень странно, что после рефреша деталей они не обновились.
Если вызов все же отрабатывает и деталь не обновляется, то могу порекомендовать программно сменить активную деталь раздела, тогда автоматически задействуется механизм обновления.

В функции RefreshDetails доходит до момента который ручками в в эту функцию вписывается для каждой детали и вызывает RefreshCommonDetail

} else 
	if (pcDetails.ActivePage.Name == pgSubContactPeriodsDetail.Name) {
		RefreshCommonDetail(BaseWorkspace, wndSubContactPeriodsDetail, 'ContactID',
			'ContactID');//ok
	}

в RefreshCommonDetail вызывается RefreshDetailDataByParentID только при запуске системы. При добавлении новой записи в датасет происходит выход из RefreshCommonDetail по условию

if ((ParentID == Window.Attributes('ParentItemID')) && !(AlwaysRefresh)) {
		return;
	}

решил попробовать сделать вот так:

} else 
	if (pcDetails.ActivePage.Name == pgSubContactPeriodsDetail.Name) {               //debugger;
		RefreshCommonDetail(BaseWorkspace, wndSubContactPeriodsDetail, 'ContactID',
			'ContactID',null,null,null,true);//ok
	}

и получилось :),
скажите, не приведет ли это к непредвиденным последствиям

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

Показать все комментарии