Нашел несколько примеров по сообществу применения функционала сообщений через SandBox.

Вот здесь: http://www.academy.terrasoft.ru/documents/docs/technic/SDK/7.4.1/ModuleDevelopmentInBPMonline.html
Содержится обещание

Более подробно механизм обмена сообщениями между модулями системы будет рассмотрен в отдельной статье SDK.

Статья не обнаружена. Просьба ткнуть носом или сообщить, что искать бесполезно..

Нравится

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

Здравствуйте.

Вот пример общения между деталями через SandBox

define("AccountBillingInfoDetailV2", [], function() {
    return {
        entitySchemaName: "AccountBillingInfo",
        details: /**SCHEMA_DETAILS*/{
        }/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
            {
                "operation": "merge",
                "name": "DataGrid",
                "values": {
                    "selectRow": {
                        "bindTo": "rowSelected"
                    }
                }
            }
        ]/**SCHEMA_DIFF*/,
        methods: {
            rowSelected: function() {
                this.sandbox.publish("RowSelectedInFirstDetail", { test: "param anything" }, [this.sandbox.id]);
                console.log("rowSelected in first detail...");
            }
        },
        messages: {
            "RowSelectedInFirstDetail": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.PUBLISH
            }
        }
    };
});
define("AccountAddressDetailV2", [], function() {
    return {
        entitySchemaName: "AccountAddress",
        details: /**SCHEMA_DETAILS*/{
        }/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
        methods: {
            init: function() {
                this.sandbox.subscribe("RowSelectedInFirstDetail", function(arg) {
                    console.log("test " + arg.test);
                }, this, [this.getSenderSandboxId()]);
            },
            getSenderSandboxId: function() {
                return this.sandbox.id.replace("_AccountAddress", "_AccountBillingInfo");
            }
        },
        messages: {
            "RowSelectedInFirstDetail": {
                mode: Terrasoft.MessageMode.PTP,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            }
        }
    };
});

Так же, в конфигурации Вы можете найти дополнительные примеры.

То есть примерно так:
Заявляем в блоке messages {} сообщение с одним наименованием, но с разным параметром направления(MessageDirectionType).

Отправляем сообщение из нужного модуля так:
this.sandbox.publish (A1,B1,C1)
A1 - Наименование сообщения, зарегистрированного в messages
B1 - массив параметров
C1 - Id сообщения, обычно = this.sandbox.id

Ловим в нужном модуле сообщение так:
this.sandbox.subscribe(A2, B2, C2, D2);
A2 - Наименование сообщения, зарегистрированного в messages
B2 - Некая функция, принимающая массив параметров в "arg" и что-то делающая полезное
С2 - объект, содержащийся в модуле-получателе.. (в обычном случае this )
D2 - ссылка на метод, возвращающий чтото?

Вот насчет последнего - мне пока не понятно.. Можете дать пояснение?

Алексей, добрый день!

Отдельной статьи по сообщениям в SDK на данный момент нет.

Ок. А может, тогда подскажете иное решение, как передать Контрагента ( Account_id) В деталь Продукты в заказе?
Я пытаюсь сделать это через sandbox, правильно ли это и есть ли более правильные пути?

"Шестаков Алексей Владимирович" написал:

Ок. А может, тогда подскажете иное решение, как передать Контрагента ( Account_id) В деталь Продукты в заказе?

Я пытаюсь сделать это через sandbox, правильно ли это и есть ли более правильные пути?

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

"Мотков Илья" написал:D2 - ссылка на метод, возвращающий чтото?
Вот насчет последнего - мне пока не понятно.. Можете дать пояснение?

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

А поскольку "this.sandbox.id" у разных схем разный, то метод этот "getSenderSandboxId" призван сгенерировать такой же идентификатор, как и у схемы, которая публикует сообщение.

Что именно содержится в this.sandbox.id, для каждой их схем, вы можете посмотреть в режиме отладки (F12) в вашем браузере. И на основании увиденного, подумать, как привести Id песочницы слушателя, к Id песочницы схемы публикации.

"Щиголь Максим" написал:Если у вас возникнут трудности с этим, можем написать пример именно по общению через sandbox страницы детали и страницы карточки.

Надеюсь, справлюсь :)
Один только вопрос: сообщения хранятся в Sandbox пока его не прочитают, или только передается между модулями и они оба должны существовать в момент publish?

Спасибо, Максим..
Подскажите еще, пожалуйста, как правильно получить данные содержащиеся в this по пути в отладчике:

this.values.DefaultValues[0].value

this.get("Order"), а именно заказ я там вижу в данном случае, не помогает.. а указывать как выше сделано, явно некошерно.

"Шестаков Алексей Владимирович" написал:
Один только вопрос: сообщения хранятся в Sandbox пока его не прочитают, или только передается между модулями и они оба должны существовать в момент publish?

Оба должны быть живы (прошли свой init, и еще не выгружены из песочницы) в момент публикации сообщения.
Когда происходит publish сообщения, sandbox смотрит есть ли кто-то из ныне живых, слушающий тот же Id песочницы что и публикующий, и, если такого находит, дает ему сообщение.

Но в вашем случае, когда вы открываете страницу редактирования детали из страницы карточки, страница карточки не удаляется, так что страница карточки и детали, могут общаться через sandbox.

На ваш второй вопрос, отвечу комментарием ниже.

"Шестаков Алексей Владимирович" написал:Подскажите еще, пожалуйста, как правильно получить данные содержащиеся в this по пути в отладчике:

Не совсем понятно задан вопрос, но постараюсь предположить что вас интересует, как в карточке заказа, получить id контрагента, что бы его передавать дальше по sandbox.

Смотрите, первое, что бы в отладчике смотреть в this именно страницы заказа, вам нужно поставить точку остановки в любом методе страницы заказа. И остановится в ней, иначе, если вы просто будете писать в консоли, то this укажет на окно браузера.

Второе, это не должен быть метод init, в нем еще не заполнены поля. Можете для целей отладки использовать метод onEntityInitialized, или onSaved, что бы посмотреть что за поля есть у заказа.

Так же учтите что в 7.7. в заказе можно покупателем указать как контакт, так и аккаунт, в зависимости от этого и получать их необходимо будет по разному,
так: this.get("Account") для контрагента,
и так: this.get("Contact") для контакта.

Вот, думаю по скриншоту станет понятно:

В точку! Именно на Init я и застрял. :smile:

Понимание происходящего так и не пришло.. Прошу о помощи... что было сделано... В карточке заказа:

define("OrderPageV2", ["OrderPageV2Resources", "GeneralDetails", "OrderConfigurationConstants",
	"BusinessRuleModule", "MoneyModule", "VisaHelper",  "ProcessModuleUtilities", "MaskHelper"],
function(Resources, GeneralDetails, OrderConfigurationConstants, BusinessRuleModule, MoneyModule,
	VisaHelper, ProcessModuleUtilities, MaskHelper) {
return {
...
methods: {
	onEntityInitialized: function() {
		this.sandbox.publish("GetAccountInOrderId", { AccId: this.get("Account").value, AccDisp: this.get("Account").displayValue}, [this.sandbox.id]);
		this.callParent(arguments);
	},			
	...
messages: {
	"GetAccountInOrderId": {
	mode: Terrasoft.MessageMode.PTP,
	direction: Terrasoft.MessageDirectionType.PUBLISH
}

В карточке добавляемого в заказ продукта:

define("OrderProductPageV2", ["BaseFiltersGenerateModule", "OrderProductPageV2Resources", "GeneralDetails", "ConfigurationConstants"],
function (BaseFiltersGenerateModule, resources, GeneralDetails, ConfigurationConstants) {
return {
...
methods : {
	onEntityInitialized : function () {
		var ContrId;
		var ContrName;
		this.sandbox.subscribe("GetAccountInOrderId", function (acc) {
			ContrId = acc.AccId;
			ContrName = acc.AccName
		}, this, [this.getSenderSandboxId]);
		this.callParent(arguments);
	},
	getSenderSandboxId : function () {
		return this.sandbox.id.replace("_SectionModuleV2_OrderSectionV2_CardModuleV2_detail_ProductOrderProductOrderProductPageV200000000-0000-0000-0000-000000000000", "_SectionModuleV2_OrderSectionV2_CardModuleV2");
	},
	...
messages : {
	"GetAccountInOrderId" : {
		mode : Terrasoft.MessageMode.PTP,
		direction : Terrasoft.MessageDirectionType.SUBSCRIBE
	}

Переменные Contr - не заполняются.. :cry:
Смущает Guid.Empty в sandbox.id карточки редактирования записи детали. Но он там есть в отладчике..
И, результата все нет.. Может, неправильно выбраны методы?

Понятно, что в случае добавления новой записи Контрагент не заполнен на onEntityInitialized, тестирую на редактировании.

Guid.Empty это нормально для не сохраненного объекта, он не должен Вас смущать, более того, Вы очень грубо приводите id песочниц к единому виду. Уверен там разница минимальна, буквально в "OrderProductOrderProductPageV2", а заменять все, вместе с Guid-ом, тем более когда у карточки заказа в id песочницы явно все это остается, не стоит.

Посмотрите в отладке, Ваши ключи песочниц по которым Вы в итоге сейчас пытаетесь связать эти две карточки, явно разные. Естественно сообщение не сработает.

Строить Id песочницы вместе с Guid-ом открытой записи разумно для того, что бы, если у вас открыто несколько карточек, в нескольких закладках браузера, что бы на изменения одной, не реагировала деталь другой, и.т.д.

Но и это не главная ошибка.
Главная ошибка сейчас в том что вы делаете publish в методе onEntityInitialized карточки заказа, а в этот момент у вас еще не открыта даже деталь.

Еще одна ошибка, что Вы зачем-то вынесли значения переменных в начало метода onEntityInitialized карточки схемы. Они не заполнятся значениями никогда. Т.к. даже когда у вас сработает колбек месседжа подписки, то контекст его выполнения будет равен контексту объекта карточки, а не метода.

Заведите себе атрибуты в карточке детали, и заполняйте их в колбеке subscribe метода.
Либо, заполняйте сразу через this.set("имя поля") необходимые вам поля. Вы же наверно хотите заполнить какие-то поля детали автоматически? Так реализуйте вначале их. Если получаете Вы это значение не для поля, то тогда используйте атрибут.

В общем вам нужно построить приблизительно такой алгоритм:

1. В карточке заказа сделайте метод: ДетальПроситДанные() в теле которой публикуйте сообщение в песочницу с именем к примеру "ДанныеПоКонтрагентуДляДетали", и данными по контрагенту.

2. В карточке заказа сделайте подписку на сообщение, с именем к примеру "ДетальПроситДанные", в колбеке которой, дергайте свой метод ДетальПроситДанные()

3. В карточке детали в методе onEntityInitialized вначале подпишитесь на сообщение "ДанныеПоКонтрагентуДляДетали", в теле которой заполняйте свои атрибуты или поля. (собственно это результат всей нашей работы)

4. Тут же, сразу после подписки, публикуйте сообщение ДетальПроситДанные, которая инициирует вашу карточку заказа, собрать всю информацию, и отправить вам в карточку детали.

Как-то так.
Если возникнут трудности, пишите свой код сюда.
Текущий явно не может выполнить поставленную цель. Так же обратите особое внимание еще раз на то что бы Id песочниц был одинаковым.

Максим, спасибо за терпение!
Уже почти результат достигнут :) Сейчас в Заказе такие методы:

sendAccountToOrderDetail: function() {
   this.sandbox.publish("GiveAccountToOrderDetail", {
      AccId: this.get("Account").value,
      AccDisp: this.get("Account").displayValue
   }, [this.sandbox.id]);
},
onEntityInitialized : function() {
   this.callParent(arguments);	
   this.sandbox.subscribe("AskAccountFromOrderDetail", this.sendAccountToOrderDetail(), this, [this.getSenderSandboxId]);
},
getSenderSandboxId : function() {
   return "SectionModuleV2_OrderSectionV2_CardModuleV2_detail_ProductOrderProductOrderProductPageV2";
},

sandbox.id Уже вставляю константой, скопировав из отладчика. пробовал как с Guid.Empty в конце id так и без него
Судя по всему именно с этим у меня сейчас проблема.
В детали так:

onEntityInitialized : function () {
   this.callParent(arguments);
   this.sandbox.subscribe("GiveAccountToOrderDetail", function (acc) {
      this.set("UsrContragents", {
         value : acc.AccId,
         displayValue : acc.AccDisp
      });
   }, this, [this.getSenderSandboxId]);
   this.sandbox.publish("AskAccountFromOrderDetail", null, [this.sandbox.id]);
},
 
getSenderSandboxId : function () {
   return "SectionModuleV2_OrderSectionV2_CardModuleV2";
},

И никак. :(

Воссоздал пример на своей базе.
Передаю на карточку детали "Продукт в заказе", сообщение из "Заказа". С значением Id контрагента заполненного в заказе.
Прилагаю полный листинг схем как карточки, так и детали.

define("OrderPageV2", ["OrderPageV2Resources", "GeneralDetails"],
function(resources, GeneralDetails) {
	return {
		entitySchemaName: "Order",
		details: /**SCHEMA_DETAILS*/{
		}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
		]/**SCHEMA_DIFF*/,
		attributes: {},
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
 
				this.sandbox.subscribe("OrderProductPageAsksForData", function(arg) {
					console.log("OrderProductPageV2 запрашивает данные прямо сейчас,");
					console.log("по Id песочницы: " + arg.sandboxId);
					// Высылаем данные.
					this.sendDataToOrderProductPage(arg.sandboxId);
				}, this, [this.sandbox.id]);
 
				console.log("Мы(OrderPageV2) подписались на сообщение: OrderProductPageAsksForData.");
				console.log("Id песочницы в этой карточке(OrderPageV2) следующий:");
				console.log(this.sandbox.id);
			},
			sendDataToOrderProductPage: function(sandboxId) {
				this.sandbox.publish("DataToOrderProductPage", { accountId: this.get("Account").value }, [sandboxId]);
				console.log("AccountId отправлен сообщением для OrderProductPageV2 по Id: " + sandboxId);
			}
		},
		rules: {},
		messages: {
			"DataToOrderProductPage": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			},
			"OrderProductPageAsksForData": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
		userCode: {}
	};
});

Схема детали:

define("OrderProductPageV2", ["BusinessRuleModule", "OrderUtilities"],
	function(BusinessRuleModule) {
		return {
			entitySchemaName: "OrderProduct",
			mixins: {},
			attributes: {},
			methods: {
				onEntityInitialized: function() {
					this.callParent(arguments);
 
					this.sandbox.subscribe("DataToOrderProductPage", function(arg) {
						console.log("OrderPageV2 передает нам данные!");
						alert("accountId: " + arg.accountId);
					}, this, [this.sandbox.id]);
 
					console.log("Мы(OrderProductPageV2) подписались на сообщение: DataToOrderProductPage.");
					console.log("По нашему(OrderProductPageV2) Id песочницы:");
					console.log(this.sandbox.id);
 
					this.sandbox.publish("OrderProductPageAsksForData", { 
						sandboxId: this.sandbox.id
					}, [this.getOrderPageSandboxId()]);
 
					console.log("Запросили данные у OrderPageV2, по её Id песочницы: " + this.getOrderPageSandboxId());
				},
				getOrderPageSandboxId: function() {
					var index = this.sandbox.id.indexOf("_detail_ProductInProducts");
					return this.sandbox.id.substring(0, index);
				}
			},
			messages: {
				"DataToOrderProductPage": {
					mode: Terrasoft.MessageMode.PTP,
					direction: Terrasoft.MessageDirectionType.SUBSCRIBE
				},
				"OrderProductPageAsksForData": {
					mode: Terrasoft.MessageMode.PTP,
					direction: Terrasoft.MessageDirectionType.PUBLISH
				}
			},
			diff: /**SCHEMA_DIFF*/[
			]/**SCHEMA_DIFF*/,
			rules: {
			}
		};
	}
);

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

Что является немного другой схемой, а именно схемой детали (OrderProductDetailV2), но, передача сообщений туда, по сути не сильно бы и отличалась. Главное понять саму механику работы с sandbox.

P.S. В результате работы вышеуказанного кода, в консоли браузера можно будет видеть:

Мы(OrderPageV2) подписались на сообщение: OrderProductPageAsksForData.
Id песочницы в этой карточке(OrderPageV2) следующий:
CardModuleV2_b8978c7f-a094-4943-bd13-2846b0ecbec9_OrderPageV2

Мы(OrderProductPageV2) подписались на сообщение: DataToOrderProductPage.
По нашему(OrderProductPageV2) Id песочницы:
CardModuleV2_b8978c7f-a094-4943-bd13-2846b0ecbec9_OrderPageV2_detail_ProductInProductsTabOrderProductOrderProductPageV200000000-0000-0000-0000-000000000000

OrderProductPageV2 запрашивает данные прямо сейчас,
по Id песочницы:
CardModuleV2_b8978c7f-a094-4943-bd13-2846b0ecbec9_OrderPageV2_detail_ProductInProductsTabOrderProductOrderProductPageV200000000-0000-0000-0000-000000000000
OrderPageV2 передает нам данные!

Ну и значение выведено алертом:

Вот это уже тянет на мануал.. Спасибо, Максим, обещаю вскоре отчитаться об успехе :)

Максим, я отразил весь ваш пример на своей базе и перепроверил и

Мы (OrderPageV2), Подписались на AskAccountFromOrderDetail, наш Sandbox.id: CardModuleV2_OrderPageV2
Мы(OrderProductPageV2) подписались на сообщение: GiveAccountToOrderDetail.
По нашему(OrderProductPageV2) Id песочницы: CardModuleV2_OrderPageV2_detail_ProductOrderProductOrderProductPageV200000000-0000-0000-0000-000000000000 
Запросили данные у OrderPageV2, по её Id песочницы: CardModuleV2_OrderPageV2

И ответ не приходит, заказ не получает сообщение и не отсылает в ответ контрагента.

В глаза бросается то, что sandbox.id в ваших логах содержит guid заказа, а в моем случае он передается и выглядит именно так, как написано в логах - без Guid. Как на Init, так и на другие события.

Версия BPM 7.5 - может это как-то влияет... следующим постом пришлю код..

Заказ:

		messages: {
			"GiveAccountToOrderDetail": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			},
			"AskAccountFromOrderDetail": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
...
onEntityInitialized : function() { // OrderPageV2
	this.callParent(arguments);
	this.sandbox.subscribe("AskAccountFromOrderDetail", function(arg) {
	    console.log("OrderProductPageV2 запрашивает данные прямо сейчас,");
  	    console.log("по Id песочницы: " + arg.sandboxId);
	this.sendAccountToOrderDetail(arg.sandboxId);
	}, this, [this.sandbox.id]);
	console.log("Мы (OrderPageV2), Подписались на AskAccountFromOrderDetail, наш Sandbox.id: " + this.sandbox.id);
},
sendAccountToOrderDetail: function(sandboxId) {
	this.sandbox.publish("GiveAccountToOrderDetail", {
		AccId: this.get("Account").value,
		AccDisp: this.get("Account").displayValue
	}, [sandboxId]);
	console.log("AccountId отправлен сообщением GiveAccountToOrderDetail для OrderProductPageV2 по Id: " + sandboxId);
},

Продукт:

		messages : {
			"GiveAccountToOrderDetail" : {
				mode : Terrasoft.MessageMode.PTP,
				direction : Terrasoft.MessageDirectionType.SUBSCRIBE
			},
			"AskAccountFromOrderDetail" : {
				mode : Terrasoft.MessageMode.PTP,
				direction : Terrasoft.MessageDirectionType.PUBLISH
			}
		},
...
onEntityInitialized: function() { // Карточка продукта в заказе
	this.callParent(arguments);
	this.sandbox.subscribe("GiveAccountToOrderDetail", function(arg) {
		this.set("UsrContragents", { value: arg.AccId, displayValue: arg.AccDisp }) 
		}, this, [this.sandbox.id]);
	console.log("Мы(OrderProductPageV2) подписались на сообщение: GiveAccountToOrderDetail.");
	console.log("По нашему(OrderProductPageV2) Id песочницы:" + this.sandbox.id);
	this.sandbox.publish("AskAccountFromOrderDetail", { sandboxId: this.sandbox.id }, [this.getOrderSandboxId]);
	console.log("Запросили данные у OrderPageV2, по её Id песочницы: " + this.getOrderSandboxId());
},
getOrderSandboxId : function() {
	var index = this.sandbox.id.indexOf("_detail_ProductOrder");
	return this.sandbox.id.substring(0, index); // обрезаем 
},

Уточнил версию :
Версия 7.5.0.1122

иногда sandbox.id в заказе бывает таким:
SectionModuleV2_OrderSectionV2_CardModuleV2
В зависимости от того, открыта ли слева в карточке заказа секция со списком заказов.
правда, на результат это не влияет.

На 7.5 проблема наблюдалась только в другом составлении ид песочницы для детали.
Получилось добиться получения ид контрагента изменением только метода getOrderSandboxId, ну и на всякий случай добавлением this. к типу и направлению сообщений.

define("OrderPageV2", ["OrderPageV2Resources", "GeneralDetails"],
function(resources, GeneralDetails) {
        return {
                entitySchemaName: "Order",
                details: /**SCHEMA_DETAILS*/{
                }/**SCHEMA_DETAILS*/,
                diff: /**SCHEMA_DIFF*/[
                ]/**SCHEMA_DIFF*/,
                attributes: {},
                methods: {
                        onEntityInitialized: function() {
                                this.callParent(arguments);
 
                                this.sandbox.subscribe("OrderProductPageAsksForData", function(arg) {
                                        console.log("OrderProductPageV2 запрашивает данные прямо сейчас,");
                                        console.log("по Id песочницы: " + arg.sandboxId);
                                        // Высылаем данные.
                                        this.sendDataToOrderProductPage(arg.sandboxId);
                                }, this, [this.sandbox.id]);
 
                                console.log("Мы(OrderPageV2) подписались на сообщение: OrderProductPageAsksForData.");
                                console.log("Id песочницы в этой карточке(OrderPageV2) следующий:");
                                console.log(this.sandbox.id);
                        },
                        sendDataToOrderProductPage: function(sandboxId) {
                                this.sandbox.publish("DataToOrderProductPage", { accountId: this.get("Account").value }, [sandboxId]);
                                console.log("AccountId отправлен сообщением для OrderProductPageV2 по Id: " + sandboxId);
                        }
                },
                rules: {},
                messages: {
                        "DataToOrderProductPage": {
                                mode: this.Terrasoft.MessageMode.PTP,
                                direction: this.Terrasoft.MessageDirectionType.PUBLISH
                        },
                        "OrderProductPageAsksForData": {
                                mode: this.Terrasoft.MessageMode.PTP,
                                direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
                        }
                },
                userCode: {}
        };
});
define("OrderProductPageV2", ["BusinessRuleModule", "OrderUtilities"],
        function(BusinessRuleModule) {
                return {
                        entitySchemaName: "OrderProduct",
                        mixins: {},
                        attributes: {},
                        methods: {
                                onEntityInitialized: function() {
                                        this.callParent(arguments);
 
                                        this.sandbox.subscribe("DataToOrderProductPage", function(arg) {
                                                console.log("OrderPageV2 передает нам данные!");
                                                alert("accountId: " + arg.accountId);
                                        }, this, [this.sandbox.id]);
 
                                        console.log("Мы(OrderProductPageV2) подписались на сообщение: DataToOrderProductPage.");
                                        console.log("По нашему(OrderProductPageV2) Id песочницы:");
                                        console.log(this.sandbox.id);
 
                                        this.sandbox.publish("OrderProductPageAsksForData", { 
                                                sandboxId: this.sandbox.id
                                        }, [this.getOrderPageSandboxId()]);
 
                                        console.log("Запросили данные у OrderPageV2, по её Id песочницы: " + this.getOrderPageSandboxId());
                                },
                                getOrderPageSandboxId: function() {
                                        var index = this.sandbox.id.indexOf("_detail");
                                        return this.sandbox.id.substring(0, index);
                                }
                        },
                        messages: {
                                "DataToOrderProductPage": {
                                        mode: this.Terrasoft.MessageMode.PTP,
                                        direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
                                },
                                "OrderProductPageAsksForData": {
                                        mode: this.Terrasoft.MessageMode.PTP,
                                        direction: this.Terrasoft.MessageDirectionType.PUBLISH
                                }
                        },
                        diff: /**SCHEMA_DIFF*/[
                        ]/**SCHEMA_DIFF*/,
                        rules: {
                        }
                };
        }
);

Если не получится и так, остается только обращаться в support@terrasoft.ru, с предоставлением учетных данных для доступа к Вашему сайту, где будет написано все вышесказанное в замещающих схемах, и останется только найти проблему, почему в конкретно вашем случае messages не отрабатывают. т.к. выше указанный код работоспособен.

Заработало! Допилил присвоение в карточке, все закрутилось-завертелось!
Большое спасибо!
Заодно получился ПочтиМануал :)

P.S. Методом массированного научного тыка обнаружилось, что в 7.7 можно получить однократно при сбросе кеша и полной перезагрузке в Chrome sandbox.id с Guid заказа.
Но при повторных обновлениях страницы или переходах по модулям Guid больше не показывается до следующего хард релоада.

Мы (OrderPageV2), Подписались на AskAccountFromOrderDetail, наш Sandbox.id: CardModuleV2_65a22318-a5ad-41e2-85a9-8c25393381e8_OrderPageV2

на 7.5 даже такого эффекта добиться не удалось :)

Максим, Добрый день! Пытаюсь в BPM 7.7 в карточке Документы сделать передачу Id контрагента в деталь с редактируемым реестром. Id аккаунта необходим для фильтрации контактов, которые выбираются на детали. Использую Ваш пример. Но в моем случае, все что находится в methods не отрабатывает. Для теста добавил функцию init, а ней debugger, функция не была вызвана.
Но правило из rules работает. Т.е. добавляю атрибут Account, значение пишу туда руками и контакты фильтруются по этому значению.
Код карточки Документы:

define('DocumentPageV2', ['DocumentPageV2Resources', 'GeneralDetails', 'BusinessRuleModule'],
function(resources, GeneralDetails, BusinessRuleModule) {
	return {
		entitySchemaName: 'Document',
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[
 
]/**SCHEMA_DIFF*/,
		attributes: {
			"UsrType": {
				dependencies : [{
					columns : ["UsrDocumentType"],
					methodName : "onDocumentTypeChanged"
				}]
			},
		},
		messages: {
			"UsrDocumentTypeColumnChanged": {
				mode: Terrasoft.MessageMode.PTP,
				direction: Terrasoft.MessageDirectionType.PUBLISH
			},
			"DataToContactInDocumentPage": {
				mode: this.Terrasoft.MessageMode.PTP,
				direction: this.Terrasoft.MessageDirectionType.PUBLISH
			},
			"ContactInDocumentPageAsksForData": {
				mode: this.Terrasoft.MessageMode.PTP,
				direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
			}
		},
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.sandbox.subscribe("ContactInDocumentPageAsksForData", function(arg) {
					// Высылаем данные.
					this.sendDataToContactInDocumentPage(arg.sandboxId);
				}, this, [this.sandbox.id]);
			},
			sendDataToContactInDocumentPage: function(sandboxId) {
				this.sandbox.publish("DataToContactInDocumentPage", { accountId: this.get("Account").value }, [sandboxId]);
			}
		},
		rules: {
 
		}
	};
});

Код карточки детали:

define("ContactInDocumentPageV2", ["BusinessRuleModule"], function(BusinessRuleModule) {
	return {
		entitySchemaName: "ContactInDocument",
		attributes: {
			"Account": {
				dataValueType: Terrasoft.DataValueType.STRING,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				value: ""
			},
		},
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		messages: {
			"DataToContactInDocumentPage": {
				mode: this.Terrasoft.MessageMode.PTP,
				direction: this.Terrasoft.MessageDirectionType.SUBSCRIBE
			},
			"ContactInDocumentPageAsksForData": {
				mode: this.Terrasoft.MessageMode.PTP,
				direction: this.Terrasoft.MessageDirectionType.PUBLISH
			}
		},
		methods: {
			onEntityInitialized: function() {
				this.callParent(arguments);
				this.sandbox.subscribe("DataToContactInDocumentPage", function(arg) {
					this.set("Account", arg.accountId);
				}, this, [this.sandbox.id]);
				this.sandbox.publish("ContactInDocumentPageAsksForData", { 
					sandboxId: this.sandbox.id
				}, [this.getDocumentPageSandboxId()]);
			},
			getDocumentPageSandboxId: function() {
				var index = this.sandbox.id.indexOf("_detail");
				return this.sandbox.id.substring(0, index);
			}
		},
		rules: {
			"UsrContact": {
				FiltrationUsrContactByAccount: {
					ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
					autocomplete: true,
					autoClean: true,
					baseAttributePatch: "Account",
					comparisonType: Terrasoft.ComparisonType.EQUAL,
					type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
					attribute: "Account"
				}
			}
		}
	};
});

Помогите, пожалуйста, разобраться.

"Эмин Юнусов" написал:Помогите, пожалуйста, разобраться.

Методы из пейджа действительно работать не будут. Но вы можете написать свою фильтрацию колонки, написав её в атрибуте пейджа, в методе фильтрации. Примерно так:
http://www.community.terrasoft.ua/forum/topic/14388
Этот метод вызывается из пейджа, при работе редактируемого реестра, в момент создания конфига текущей строки.

"Мотков Илья" написал:
Но вы можете написать свою фильтрацию колонки, написав её в атрибуте пейджа, в методе фильтрации

Не получается передать accountId в функцию метода фильтрации. Через сообщение не выходит, т.к. метод завершает свою работу и функция в subscribe

this.sandbox.subscribe("DataToContactInDocumentPage", function(arg) {
                                        this.set("Account", arg.accountId);
                                }, this, [this.sandbox.id]);

вообще не отрабатывает.

Попробуйте заставить метод подождать результата. Объявите какой-нибудь флаг, и цикл пока флаг «ложь», по возвращению результата песочницей, меняйте флаг, и только тогда метод фильтрации вернет результат, с учетом того что вернула песочница.

function(query) {
  var r;
  myApi.exec('SomeCommand', function(response) {
    r = response;
  });
  while (!r) {}
  return r;
}
Показать все комментарии