Изменение поля при изменении детали 7.7

Есть обычная страница(карточка) раздела. Есть обычная деталь на этой странице. Нужно динамически при изменении одной записи на детали выводить итоговое значение всех записей детали на главной странице. Мот можно сделать БП который это проделывает, но нужно еще обновление страницы.
Вот есть похожая тема, но тут про реестр https://community.terrasoft.ua/forum/topic/10190

Нравится

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

можно не обновлять всю страницу, а просто считать значение поля из базы данных (так в счете считывается сумма счета при добавлении продуктов)

Не получается, вот как делаю:
details: /**SCHEMA_DETAILS*/{
"UsrSplitbbf096611929": {
"schemaName": "UsrSplitDetail",
"entitySchemaName": "UsrSplit",
"filter": {
"detailColumn": "UsrInvoice",
"masterColumn": "Id"
},
subscriber: function() {
this.setMyFEnabled();
}
}
}

methods: {
setMyFEnabled: function() {
console.log("**test**");
}
}
В консоль ничего не выводит при изменении детали

Виталий, добавьте следующие методы в схему, в которой вызываете сабскрайбер:

subscribeDetailEvents: function(detailConfig, detailName) {
    this.callParent(arguments);
    var detailId = this.getDetailId(detailName);
    var detail = this.Terrasoft.deepClone(detailConfig);
    var sandbox = this.sandbox;
    sandbox.subscribe("DetailChanged", function(args) {
        return this.onDetailChanged(detail, args);
    }, this, [detailId]);
},
onDetailChanged: function(detail, args) {
    var subscriber = detail.subscriber;
    if (this.Ext.isFunction(subscriber)) {
        subscriber.call(this, args);
    } else if (this.Ext.isObject(subscriber)) {
        var methodName = subscriber.methodName;
        if (this.Ext.isFunction(this[methodName])) {
            this[methodName](args);
        }
    }
}

Без данных методов subscriber не работает во многих разделах системы.

Написал, не помогло. Я не думаю что в этом проблема, в родительской схеме успешно используется сабскрайбер.

Виталий, скопировал Ваш код в схему редактирования контактов - код не работает.
Добавил методы описанные выше - код успешно отрабатывает. Вот листинг кода:

"UsrTestTest": {
	"schemaName": "UsrSchema4Detail",
	"entitySchemaName": "UsrTestTest",
	"filter": {
		"detailColumn": "CreatedBy",
		"masterColumn": "Id"
	},
	subscriber: function(){
		this.test();
		debugger;
	}
}
methods: {
	test: function(){
		alert("!");
	},
	subscribeDetailEvents: function(detailConfig, detailName) {
		this.callParent(arguments);
		var detailId = this.getDetailId(detailName);
		var detail = this.Terrasoft.deepClone(detailConfig);
		var sandbox = this.sandbox;
		sandbox.subscribe("DetailChanged", function(args) {
			return this.onDetailChanged(detail, args);
		}, this, [detailId]);
	},
	onDetailChanged: function(detail, args) {
		var subscriber = detail.subscriber;
		if (this.Ext.isFunction(subscriber)) {
			subscriber.call(this, args);
		} else if (this.Ext.isObject(subscriber)) {
			var methodName = subscriber.methodName;
			if (this.Ext.isFunction(this[methodName])) {
				this[methodName](args);
			}
		}
	}
},

Так же, Вы можете использовать sandbox на прямую. Его использование детально обсуждалось в этой теме.

Вот что паказывает консоль когда меняю значение на детале:
"Method generatActiveRowControlsConfig is obsolete. Use generateActiveRowControlsConfig instead baseobject.js:85:5
Method handler is obsolete. Use click event instead"
Прилагаю схему:
invoicepage2.txt
Не судите строго за код, только разбираюсь в BPMonline

Виталий, данное сообщение не свидетельствует об ошибке. Это предупреждение о том, что был вызван метод, помеченный как устаревший и не рекомендуемый впредь к использованию.

А может быть причина в том, что эта деталь - полноценный раздел, просто грид отображается?

Виталий, уточните, заработал ли subscriber? Данные сообщения в консоли никак не влияют на работу приложения. Если заработал, то Вам осталось в методе вызываемом сабскрайбером сделать запрос к базе данных используя entitySchemaQuery, а затем обновить поля основываясь на полученном результате. Для обновления полей воспользуйтесь методом this.set("Имя колонки", новое значение).

subscriber к сожалению не заработал, начал делать через sandbox. Даже что то получилось, в консоль удалось выводить пометки когда делаю изменения на детале, но передать в основную карточку никак не получается. Вот мой код:
invoicepage2.txt
Страница какбы загружается, но пишет "Загрузка" и все заблокировано.
Я уже не знаю что делать....

Добавил в onEntityInitialized строку this.callParent(arguments);и страница загрузилась но сообщение так и не ловит

Виталий, предоставте код схемы карточки детали в которой Вы публикуете данное сообщение. Так же уточните, создавалась ли деталь через Мастер деталей?

Деталь это всего лишь редактируемый грид другого раздела, это все было создано до меня.
вод код детали:

define("UsrSplitDetail", ["terrasoft", "ConfigurationEnums", "ConfigurationGrid", "ConfigurationGridGenerator",
"ConfigurationGridUtilities"],
function(Terrasoft, configurationEnums) {
	return {
		entitySchemaName: "UsrSplit",
		attributes: {},
		methods: {
			onActiveRowSave: function() {
				this.sandbox.publish("Test1", { test: "param anything" }, [this.sandbox.id]);
				console.log("rowSelected in first detail..." + this.sandbox.id);
			}
		},
		messages: {
			"Test1": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			}
		}
	};
});

Сделал замещающую схему детали и там дописал нужный мне код.

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

Виталий, вот пример кода для детали с редактируемым реестром.

Страница контакта:

      messages: {
		"Test1": {
			mode: this.Terrasoft.MessageMode.PTP,
			direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
		}
      },
		methods: {
			init: function(){
				this.sandbox.subscribe("Test1", function() {
					alert("Great");
				}, this, ["111"]);
				this.callParent(arguments);
			}
		},

Деталь:

define("UsrSchema1Detail", ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"], function() {
	return {
		entitySchemaName: "UsrTestTest",
		attributes: {
			"IsEditable": {
				dataValueType: Terrasoft.DataValueType.BOOLEAN,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				value: true
			}
		},
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: [
			{
				"operation": "merge",
				"name": "DataGrid",
				"values": {
					"className": "Terrasoft.ConfigurationGrid",
					"generator": "ConfigurationGridGenerator.generatePartial",
					"generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
					"changeRow": {"bindTo": "changeRow"},
					"unSelectRow": {"bindTo": "unSelectRow"},
					"onGridClick": {"bindTo": "onGridClick"},
					"activeRowActions": [
						{
							"className": "Terrasoft.Button",
							"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
							"tag": "save",
							"markerValue": "save",
							"imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
						},
						{
							"className": "Terrasoft.Button",
							"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
							"tag": "cancel",
							"markerValue": "cancel",
							"imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
						},
						{
							"className": "Terrasoft.Button",
							"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
							"tag": "remove",
							"markerValue": "remove",
							"imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
						}
					],
					"initActiveRowKeyMap": {"bindTo": "initActiveRowKeyMap"},
					"activeRowAction": {"bindTo": "onActiveRowAction"},
					"multiSelect": false
				}
			}
		],
		mixins: {
			ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities"
		},
		methods: {
			int: function(){
				alert("!");
				this.callParent(arguments);
			},
			saveRowChanges: function(row, callback, scope) {
				scope = scope || this;
				callback = callback || this.Terrasoft.emptyFn;
				if (row && this.getIsRowChanged(row)) {
					scope.sandbox.publish("Test1", null, ["111"]);
					row.save({
						callback: callback,
						isSilent: true,
						scope: scope
					});
				} else {
					callback.call(scope);
				}
			}
		},
		messages: {
			"Test1": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			}
		}
	};
});

Данный код будет отрабатывать при изменении любого поля детали с последующим сохранением. Для удаления нужно будет переопределить метод deleteRecords.

О дааа!!! Я сделал это!!! Оно сработало!!!
Но все-же есть где то список функций?
например:
saveRowChanges
init
onActiveRowSave
onEntityInitialized
и тд. Это намного упростило бы не жизнь .

Виталий, часть этих методов описана в миксине "ConfigurationGridUtilities", там описаны методы которые нужны для работы редактируемого грида. Остальные же описаны в BasePageV2 (init, onEntityInitialized).

Далее все как по маслу пошло, с entitySchemaQuery разобрался быстро, есть много примеров на комюнити, да и в отладке поиском найти можна

Добрый день! Очень полезная тема, сильно помогла. Только есть один нюанс, сообщение публикуется до момента сохранения записи в базу. Как это обойти? Подскажите, пожалуйста, метод, который отрабатывает после сохранения записи, чтобы сообщение опубликовать из него.

Александр, Вам необходимо смотреть в сторону замещения метода save из схемы BasePageV2 и публиковать сообщение из него.

Правда работает. Опубликовал сообщение из onSaved. Спасибо

Добрый день.
Изменяю в редактируемом реестре данные, при помощи кода

 #5 Мотков Илья 6 апреля 2016 – 10:54 

У меня работает, но данные еще не сохранены в БД.
Подскажите может какой то еще метод есть которым могу воспользоваться, после добавления данных в БД ?

Марат, Вам необходимо смотреть в сторону замещения методов activeRowSaved (ConfigurationGridUtilities) в схеме детали или onSaved в карточке детали (в детали с редактируемым реестром он также вызывается).

Добрый день!
Подскажите как можно вытянуть данные из детали. Нужно выполнить расчёты на основании данных детали и поместить их на страницу реестра. использовать entitySchemaQuery? или же можно как то ещё получить значения?

Здравствуйте, Евгений.

Если данные присутствуют в реестре детали (уже отрисовались в гриде) - Вы можете их получить используя sandbox и атрибут GridData в схеме детали. Если же данных нет - только ESQ.

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