Всем доброго времени суток.
Версия 7.10.
Ситуация такая: сделал свой контрол в соответствии с инструкцией из комментариев отсюда: https://community.terrasoft.ru/forum/topic/25285#comment-67717
Контрол похож на то, что описано там, разница в том, что добавляет не div, а элемент canvas с определённым id в DOM на страницу контакта. Пробуем для решения определённой задачи (образец подписи клиента, получается через canvas и сохраняется в отдельную колонку в формате base64).
Далее в onEntityInitialized ContactPageV2 делаю следующее:
this.callParent(arguments);
var canvas = document.getElementById("UsrTestUsrSignControl-usr-my-control");
var context = canvas.getContext("2d");
//Дальнейшие действия
},
UsrTestUsrSignControl-usr-my-control - id элемента canvas.
Обнаружил, что в некоторых случаях на стадии getContext вываливается ошибка - скрипт не находит элемента по id. При это именно взятие по id необходимо для работы с канвасом, а работа внутри ContactPageV2 - чтобы сохранить результат в колонку контакта.
Вопрос - можно ли как-нибудь отследить загрузку контрола на страницу? Может быть, внутри самого контрола? Попробовал добавить document.getElementById внутрь init - то же самое.
Нравится
Обнаружил, что элемент доступен внутри события initDomEvents
Соответственно, вопрос меняется на "как передать данные в ContactPage".
Может быть, через sandbox?
Загрузка всех элементов на страницу "asynchronous as fuck", как говорится. В onEntityInitialized доступна модель страницы, но не факт, что элементы погрузились. Можно попробовать вставить функцию, реагирующую на рендер контрола:
"values": { .... "afterrender": {bindTo: "onControlRendered"} }
Данила, а точно есть такое - afterrender? Может быть onRender?
Попробовал - вообще функция не вызывается. Добавляю в values при подключении контрола.
Здравствуйте,
Можете подписатся в init-е на событие добавления в dom вашего элемента, подробнее:
https://toster.ru/q/18926
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_even…
"Смородинов Денис" написал:Данила, а точно есть такое - afterrender?
У Terrasoft.Label есть. Вообще должно событие быть, если контрол наследуется от Terrasoft.Component.
Судя по NUI Docs
{ "operation": "insert", "name": "UsrTest", "values": { "layout": { "colSpan": 12, "rowSpan": 1, "column": 0, "row": 0, "layoutName": "GeneralInfoTabGridLayout97349c91", }, "onAfterRender": { "bindTo": "onCanvasRendered" }, "generator": "UsrSignControlGenerator.generateUsrSignControl", "visible": true }, "parentName": "GeneralInfoTabGridLayout97349c91", "propertyName": "items", "index": 0 },
И в методах:
onCanvasRendered: function(){ console.log("rendered"); var canvas = document.getElementById("UsrTestUsrSignControl-usr-my-control"); console.log(canvas); },
Так не работает, даже просто "rendered" не выводит. afterrender вместо onAfterRender - тоже.
Контрол сам точно по той схеме, т.е. наследуется от компонента.
"Смородинов Денис" написал:Соответственно, вопрос меняется на "как передать данные в ContactPage".Может быть, через sandbox?
Возможно, этот путь будет проще?
"Смородинов Денис" написал:Возможно, этот путь будет проще?
Думаю нет)
Получилось вот так (подправил генератор из вашей ссылки в посте):
generateTmMyControl: function(config) { debugger; var TmMyControl = { className: "Terrasoft.TmMyControl", id: config.name + "TmMyControl", selectors: {wrapEl: "#" + config.name + "TmMyControl"}, layout: config.layout || {}, afterrender: {bindTo: config.onAfterRender}, //добавил чисто на всякий случай afterrerender: {bindTo: config.onAfterRender} //контрол почему-то ререндерится, у меня на тестовой системе срабатывает именно это событие }; if (!Ext.isEmpty(config.wrapClassName)) { TmMyControl.classes = { wrapClassName: config.wrapClassName }; } return TmMyControl; },
Данила, спасибо, работает!
То есть получается, методы нужно добавлять в генератор.
"Варфоломеев Данила" написал:Получилось вот так (подправил генератор из вашей ссылки в посте)
Привет. Есть ли идеи вот насчет чего?:
{ "operation": "insert", "name": "Containment", "values": { "itemType": 2, "markerValue": "added-detail", "afterrender": { "bindTo": "getEnableDetails" }, "afterrerender": { "bindTo": "getEnableDetails" } }, "parentName": "QuickAnalysisTabContainer", "propertyName": "items", "index": 6 }
Соответственно, сам метод, который вешается на послерендер допустим что-то выводит в консоль.
На детали очень странное поведение.
Как только открываю табу, на которой должна быть деталь - моментально идет вызов метода и вывод в консоль. При этом сама деталь не грузится и запросы никакие никуда не идут на получение детали и её данных. Это оочень странно. И в DOM-е ни одного упоминания об этой детали. Т.е. грубо говоря вообще никакого рендера не произошло. Деталь не появляется на карточке. Никак.
ЧЯДНТ?
"Темченко Кирилл Александрович" написал:Деталь не появляется на карточке.
Смотрим стандартный генератор детали:
generateDetail: function(config) { var detailContainerId = this.getControlId(config, "Terrasoft.Container"); var result = this.getDefaultContainerConfig(detailContainerId, config); result.tag = { detailName: config.name, containerId: detailContainerId }; result.markerValue = config.name + "DetailContainer"; result.afterrender = { bindTo: this.defaultLoadDetailMethodName }; result.afterrerender = { bindTo: this.defaultLoadDetailMethodName }; Ext.apply(result, this.getConfigWithoutServiceProperties(config, [])); this.applyControlConfig(result, config); return result; },
Видно, что на afterrender и afterrerender вешается метод loadDetail. (this.defaultLoadDetailMethodName = "loadDetail"). Далее ваши конфиг из диффа перетирает рендеры - this.applyControlConfig(result, config)
В итоге. Как задумывалось: рендерится контейнер, после рендера в него грузится грид детали (уж не знаю что там в методе loadDetail)
Как происходит: рендерится контейнер, вызываются ваши методы. деталь соответственно не загружается.
п.с. это всё в теории, времи тестить совсем нет)
"Варфоломеев Данила" написал:п.с. это всё в теории, времи тестить совсем нет)
я на то и подумал. семантически это, конечно, не комильфо. на то оно и after. и когда я привязываю свои методы, по идее не должен задумываться, что уже висит что-то ванильное, которое я затру. ну да и ладно. задачу решил по-своему. через DOM события.
спасибо за помощь.