Вопрос

Имеется иерархическая деталь с редактируемым реестром. В ней возникает проблема при сохранении дробного числа. Появляется ошибка Cannot read property 'getAttribute' of null, которая возникает в результате того, что метод GetDomRow возвращает undefined. После этого я не могу больше сохранять дробные числа в реестре и приходится перезагружать страницу. Первое сохранение проходит удачно, хоть и успевает появиться ошибка. В результате чего возникает такая проблема? ниже представлен код детали

define("IDSBRefrigeratorInTMADetail",
    ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities", "ServiceHelper"],
    function (ConfigurationGrid, ConfigurationGridGenerator, ConfigurationGridUtilities, ServiceHelper) {
        return {
            messages: {
                "ReloadRefrigeratorsInTMAGrid": {
                    "mode": Terrasoft.MessageMode.BROADCAST,
                    "direction": Terrasoft.MessageDirectionType.SUBSCRIBE
                }
            },
            entitySchemaName: "IDSBRefrigeratorInTMA",
            attributes: {
                "IsEditable": {
                    dataValueType: Terrasoft.DataValueType.BOOLEAN,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    value: true
                }
            },
            mixins: {
                ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
            },
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "DataGrid",
                    "values": {
                        "hierarchical": true,
                        "hierarchicalColumnName": "IDSBParent",
                        "className": "Terrasoft.ConfigurationGrid",
                        "generator": "ConfigurationGridGenerator.generatePartial",
                        "generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
                        "changeRow": { "bindTo": "changeRow" },
                        "unSelectRow": { "bindTo": "unSelectRow" },
                        "onGridClick": { "bindTo": "onGridClick" },
                        "activeRowAction": { "bindTo": "onActiveRowAction" },
                        "initActiveRowKeyMap": { "bindTo": "initActiveRowKeyMap" },
                        "multiSelect": false
                    }
                },
                {
                    "operation": "remove",
                    "name": "AddRecordButton"
                }]/**SCHEMA_DIFF*/,
            methods: {
                generateActiveRowControlsConfig: function (id, columnsConfig, rowConfig) {
                    this.columnsConfig = columnsConfig;
                    var gridData = this.getGridData();
                    var activeRow = gridData.get(id);
                    var isEditableColumn;
                    if (activeRow.values.IDSBParent === "") {
                        isEditableColumn = this.ParentColumnIsEditable;
                    }
                    else {
                        isEditableColumn = this.ColumnIsEditable;
                    }
                    var gridLayoutItems = [];
                    var currentColumnIndex = 0;
                    Terrasoft.each(columnsConfig, function (columnConfig) {
                        var cellConfig = this.getActiveRowCellConfig(columnConfig, currentColumnIndex);
                        cellConfig.enabled = isEditableColumn(cellConfig.name);
                        if (!cellConfig.hasOwnProperty("isNotFound")) {
                            gridLayoutItems.push(cellConfig);
                        }
                        currentColumnIndex += cellConfig.layout.colSpan;
                    }, this);
                    this.applyBusinessRulesForActiveRow(id, gridLayoutItems);
                    var viewGenerator = Ext.create(this.getRowViewGeneratorClassName());
                    viewGenerator.viewModelClass = this;
                    var gridLayoutConfig = viewGenerator.generateGridLayout({
                        name: this.name,
                        items: gridLayoutItems
                    });
                    rowConfig.push(gridLayoutConfig);
                },
                ParentColumnIsEditable: function (columnName) {
                    return (columnName === "IDSBPlacementPrice" || columnName === "IDSBNumberOfDoors" || columnName === "IDSBProlongation");
                },
                ColumnIsEditable: function (columnName) {
                    return (columnName === "IDSBRBBottlePlan" || columnName === "IDSBRBBottleCurrent"
                        || columnName === "IDSBBRBottlePlan" || columnName === "IDSBBRBottleCurrent");
                },
                init: function () {
                    this.callParent(arguments);
                    this.set("IsPageable", false);
                    this.set("RowCount", 28000);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },
                onReloadRefrigeratorsInTMAGrid: function (args) {
                    var id = this.get("MasterRecordId");
                    debugger;
                    if (id === args) {
                        this.reloadGridData();
                    }
                },
                addGridDataColumns: function (esq) {
                    this.callParent(arguments);
                    if (!esq.columns.contains("IDSBParent")) {
                        esq.addColumn("IDSBParent");
                    }
                },
                getGridDataColumns: function () {
                    var gridDataColumns = this.callParent(arguments);
                    if (!gridDataColumns.IDSBParent) {
                        gridDataColumns.IDSBParent = {
                            path: "IDSBParent"
                        };
                    }
                    return gridDataColumns;
                },
                addToolsButtonMenuItems: function (toolsButtonMenu) {
                    this.addGridOperationsMenuItems(toolsButtonMenu);
                    if (this.useDetailWizard) {
                        this.addDetailWizardMenuItems(toolsButtonMenu);
                    }
                },
                prepareResponseCollection: function (collection) {
                    collection.each(function (item) {
                        var parent = item.get("IDSBParent");
                        var parentId = parent && parent.value;
                        if (parentId) {
                            item.set("IDSBParentId", parentId);
                        }
                        Terrasoft.each(item.columns, function (column) {
                            this.addColumnLink(item, column);
                            this.applyColumnDefaults(column);
                        }, this);
                    }, this);
                }
            }
        };
    });

У меня такой же вопрос

2 комментария

Навряд ли кто то взглянув на не один десяток строк кода ответит вам почему возникает проблема при сохранении (скорее всего редактируемость и иерархичность не совместимы).

В любом случае вам может помочь только отладка кода!

решил задачу тупо влоб, переопределив метод сохранения. Написал своё сохранение, вызывая сервис из сервера. немного медленно, но работает

saveRowChanges: function (row, callback, scope) {
                    scope = scope || this;
                    callback = callback || Terrasoft.emptyFn;
                    if (row && this.getIsRowChanged(row)) {
                        if (row.values.IDSBParent !== "") {
                            this.saveChildRow(row, callback, scope);
                        }
                        else {
                            this.saveParentRow(rowm, callback, scope);
                        }
                    } else {
                        callback.call(scope);
                    }
                },
saveChildRow: function (row, callback, scope) {
                    var changed = row.changedValues;
                    debugger;
                    if (!changed.hasOwnProperty("IDSBBRBottleCurrent")) {
                        changed.IDSBBRBottleCurrent = row.values.IDSBBRBottleCurrent;
                    }
                    if (!changed.hasOwnProperty("IDSBBRBottlePlan")) {
                        changed.IDSBBRBottlePlan = row.values.IDSBBRBottlePlan;
                    }
                    if (!changed.hasOwnProperty("IDSBRBBottlePlan")) {
                        changed.IDSBRBBottlePlan = row.values.IDSBRBBottlePlan;
                    }
                    if (!changed.hasOwnProperty("IDSBRBBottleCurrent")) {
                        changed.IDSBRBBottleCurrent = row.values.IDSBRBBottleCurrent;
                    }
                    callback = this.reloadGridData;
                    var serviceSaveData = {
                        RowId: row.values.Id,
                        bottles: changed
                    }
                    ServiceHelper.callService("IDSBPlacingREService", "SaveChildRow",
                        callback, serviceSaveData, scope);
                }

 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Создал иерархическую деталь с редактируемым реестром. Но появилась проблема при количестве дочерних элементов больше 8. Они почему не отображаются, выдается ошибка Cannot read property 'getAttribute' of null. В БД всё верно. 

Вот код детали

define("IDSBRefrigeratorInTMADetail",
    ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
    function () {
        return {
            messages: {
                "ReloadRefrigeratorsInTMAGrid": {
                    "mode": Terrasoft.MessageMode.BROADCAST,
                    "direction": Terrasoft.MessageDirectionType.SUBSCRIBE
                }
            },
            entitySchemaName: "IDSBRefrigeratorInTMA",
            attributes: {
                "IsEditable": {
                    dataValueType: Terrasoft.DataValueType.BOOLEAN,
                    type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    value: true
                }
            },
            mixins: {
                ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
            },
            details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "merge",
                    "name": "DataGrid",
                    "values": {
                        "hierarchical": true,
                        "hierarchicalColumnName": "IDSBParent",
                        "maxColumns": 48,
                        "maxRowsCount": 10000,
                        "className": "Terrasoft.ConfigurationGrid",
                        "generator": "ConfigurationGridGenerator.generatePartial",
                        "generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
                        "changeRow": { "bindTo": "changeRow" },
                        "unSelectRow": { "bindTo": "unSelectRow" },
                        "onGridClick": { "bindTo": "onGridClick" },
                        "activeRowAction": { "bindTo": "onActiveRowAction" },
                        "initActiveRowKeyMap": { "bindTo": "initActiveRowKeyMap" },
                        "multiSelect": false
                    }
                },
                {
                    "operation": "remove",
                    "name": "AddRecordButton"
                }]/**SCHEMA_DIFF*/,
            methods: {
                generateActiveRowControlsConfig: function (id, columnsConfig, rowConfig) {
                    this.columnsConfig = columnsConfig;
                    var gridData = this.getGridData();
                    var activeRow = gridData.get(id);
                    var isEditableColumn;
                    if (activeRow.values.IDSBParent === "") {
                        isEditableColumn = this.isEditableParentColumn;
                    }
                    else {
                        isEditableColumn = this.isEditableColumn;
                    }
                    var gridLayoutItems = [];
                    var currentColumnIndex = 0;
                    Terrasoft.each(columnsConfig, function (columnConfig) {
                        var cellConfig = this.getActiveRowCellConfig(columnConfig, currentColumnIndex);
                        cellConfig.enabled = isEditableColumn(cellConfig.name);
                        if (!cellConfig.hasOwnProperty("isNotFound")) {
                            gridLayoutItems.push(cellConfig);
                        }
                        currentColumnIndex += cellConfig.layout.colSpan;
                    }, this);
                    this.applyBusinessRulesForActiveRow(id, gridLayoutItems);
                    var viewGenerator = Ext.create(this.getRowViewGeneratorClassName());
                    viewGenerator.viewModelClass = this;
                    var gridLayoutConfig = viewGenerator.generateGridLayout({
                        name: this.name,
                        items: gridLayoutItems
                    });
                    rowConfig.push(gridLayoutConfig);
                },
                isEditableParentColumn: function (columnName) {
                    return false;
                },
                isEditableColumn: function (columnName) {
                    return (columnName === "IDSBBottlePlan");
                }/*,
                init: function () {
                    this.callParent(arguments);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },
                onReloadRefrigeratorsInTMAGrid: function (args) {
                    this.reloadGridData();
                }*/
            }
	};
});

 

У меня такой же вопрос

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

Для упрощения отладки посмотрите SQL профайлером запросы которые отправляются в БД.

Григорий Чех, думаете нужно заместить метод addGridDataColumns?

Григорий имел в виду использование профайлера. Естественно, только для случаев, когда есть доступ к серверу БД.

посмотрел профайлер. Выполняется следующий запрос. Забил его сам в SQL Management. Выдал недостающие элементы, которые как раз невыведены на экран. Ошибка возникает когда нажимаю "Показать больше"

SELECT
	[IDSBRefrigeratorInTMA].[Id] [Id],
	[IDSBRefrigeratorInTMA].[IDSBStreet] [IDSBStreet],
	[IDSBRefrigeratorInTMA].[IDSBCustomerInTMAId] [IDSBCustomerInTMAId],
	[IDSBRefrigeratorInTMA].[ITTradeMarketId] [ITTradeMarketId],
	[ITTradeMarket].[ITName] [ITTradeMarket.ITName],
	[IDSBRefrigeratorInTMA].[MonthId] [MonthId],
	[Month].[Name] [Month.Name],
	[IDSBRefrigeratorInTMA].[IDSBBottlePlan] [IDSBBottlePlan],
	[IDSBRefrigeratorInTMA].[IDSBParentId] [IDSBParentId],
	[IDSBParent].[IDSBStreet] [IDSBParent.IDSBStreet],
	[ITTradeMarket].[ITTypeId] [ITTradeMarket.ITTypeId],
	[ITType].[Name] [ITType.Name],
	(
SELECT
	COUNT([SubEntryPoint].[Id]) [Count]
FROM
	[dbo].[EntryPoint] [SubEntryPoint] WITH(NOLOCK)
WHERE
	[SubEntryPoint].[EntityId] = [IDSBRefrigeratorInTMA].[Id]
	AND [SubEntryPoint].[IsActive] = 1) [SubEntryPoint],
	[IDSBRefrigeratorInTMA].[CreatedOn] [CreatedOn],
	[IDSBRefrigeratorInTMA].[CreatedById] [CreatedById],
	[CreatedBy].[Name] [CreatedBy.Name],
	[CreatedBy].[PhotoId] [CreatedBy.PhotoId],
	[IDSBRefrigeratorInTMA].[ModifiedOn] [ModifiedOn],
	[IDSBRefrigeratorInTMA].[ModifiedById] [ModifiedById],
	[ModifiedBy].[Name] [ModifiedBy.Name],
	[ModifiedBy].[PhotoId] [ModifiedBy.PhotoId],
	[IDSBRefrigeratorInTMA].[ProcessListeners] [ProcessListeners]
FROM
	[dbo].[IDSBRefrigeratorInTMA] [IDSBRefrigeratorInTMA] WITH(NOLOCK)
	LEFT OUTER JOIN [dbo].[ITTradeMarket] [ITTradeMarket] WITH(NOLOCK) ON ([ITTradeMarket].[Id] = [IDSBRefrigeratorInTMA].[ITTradeMarketId])
	LEFT OUTER JOIN [dbo].[Month] [Month] WITH(NOLOCK) ON ([Month].[Id] = [IDSBRefrigeratorInTMA].[MonthId])
	LEFT OUTER JOIN [dbo].[IDSBRefrigeratorInTMA] [IDSBParent] WITH(NOLOCK) ON ([IDSBParent].[Id] = [IDSBRefrigeratorInTMA].[IDSBParentId])
	LEFT OUTER JOIN [dbo].[ITITTradeMarketType1] [ITType] WITH(NOLOCK) ON ([ITType].[Id] = [ITTradeMarket].[ITTypeId])
	LEFT OUTER JOIN [dbo].[Contact] [CreatedBy] WITH(NOLOCK) ON ([CreatedBy].[Id] = [IDSBRefrigeratorInTMA].[CreatedById])
	LEFT OUTER JOIN [dbo].[Contact] [ModifiedBy] WITH(NOLOCK) ON ([ModifiedBy].[Id] = [IDSBRefrigeratorInTMA].[ModifiedById])
WHERE
	[IDSBRefrigeratorInTMA].[ITTradeMarketId] = '54368FDE-6D00-4BDE-BAAE-EDEA56EBAA33'
ORDER BY
	[Id] ASC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

 

Может, 8 элементов видно как раз из-за выборки порциями по 10? Судя по окончанию SQL-запроса, это как раз вторая десятка, первая пропущена.

А где именно вылетает «Cannot read property 'getAttribute' of null», полный стек не видно?

Вылетает на этом методе. В строке var n = this.getDomRow(i) в n кладется undefined и далее соответственно вылетает ошибка. В i в этот момент родительская колонка

onCollectionDataLoaded: function(e, t, a) {
        if (this.theoreticallyActiveRows = null,
        !this.rows.length)
            return this.collection = this.collection || e,
            this.prepareCollectionData(),
            void this.safeRerender();
        if (!Ext.Object.isEmpty(t) && this.rendered) {
            var r = []
              , s = {
                rows: r
            };
            if (t.each(function(e) {
                this.prepareCollectionItem(e);
                var t = this.getRow(e);
                r.push(t),
                a && ("top" !== a.mode ? this.rows.push(t) : this.rows.splice(0, 0, t))
            }, this),
            this.hierarchical && !t.isEmpty()) {
                var i = t.getByIndex(0).get(this.hierarchicalColumnName);
                if (s[this.hierarchicalColumnName] = i,
                "listed" === this.type && i) {
                    var n = this.getDomRow(i)
                      , o = parseInt(n.getAttribute("level"), 10);
                    s.rowLevel = o + 1
                }
            }
            var l = [];
            this.renderGrid(l, s);
            for (var c = "", h = 0, u = l.length; h < u; h += 1)
                c += Ext.DomHelper.createHtml(l[h]);
            Ext.Object.isEmpty(a) && (a = {
                mode: "bottom"
            }),
            this.addRows(c, a),
            this.checkNeedLoadData()
        }
    },

 

Что-то не могу найти такой функции в «коробке».

А иерархичность и редактируемость сами по себе совместимы? На других таких деталях ограничения в 8 нет?

Если убираю редактируемость, ошибка не исчезает. Если убираю иерархичность, всё отображается нормально

Это логично, если сбой при превышении 8 потомков. В плоской детали никаких потомков нет. Сравните с другими иерархическими деталями, есть там такое ограничение или нет?

Решил проблему. Добавил значения атрибутов, чтобы всё грузилось сразу. В моем случае такое решение вполне подходит

init: function () {
                    this.callParent(arguments);
                    this.set("IsPageable", false);
                    this.set("RowCount", 28000);
                    this.sandbox.subscribe("ReloadRefrigeratorsInTMAGrid", this.onReloadRefrigeratorsInTMAGrid, this);
                },

 

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

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Здравствуйте, возможно ли открыть страницу записи детали по URL ссылке, используя Id записи?

Проблема, на странице редактирования "Контакта" есть деталь, хотелось бы получить url записей этой детали, при открытии детали в адресной строке браузера по прежнему такое 

http://[someSite]/Nui/ViewModule.aspx#CardModuleV2/ContactPageV2/edit/a36a54a2-3c6c-44eb-aa2f-a7e75305270a , 

не url детали.

Спасибо

У меня такой же вопрос

2 комментария
Лучший ответ

Добрый день!
Да, BPM не меняет адрес в адресной строке.
Адрес записи детали будет следующим:
ttp://[someSite]/Nui/ViewModule.aspx#CardModuleV2/[Страница редактирования записи детали]/edit/[Id записи детали]

Добрый день!
Да, BPM не меняет адрес в адресной строке.
Адрес записи детали будет следующим:
ttp://[someSite]/Nui/ViewModule.aspx#CardModuleV2/[Страница редактирования записи детали]/edit/[Id записи детали]

Сидоров Александр В.,

Спасибо, так раньше пробовал не получилось, оказалось одна буква была не в том регистре.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

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

Есть три сущности:

Order (id)

OrderProduct (id, OrderId, usrDocumentId)

usrDocument (id, usrName)

Необходимо на странице Заказы отобразить все Документы, прямой связи между Заказами и Документами нет, т.к. используется связь многие ко многим.

В sql запрос выглядит следующим образом:

Select d.Name

from Order o

join OrderProduct op on op.OrderId = o.id

join Document d on d.id = op.DocumentId

 

Как правильно прописать связь в detailColumn?

            "DocumentsDetail": {
                "schemaName": "DocumentsDetailV2",
                "entitySchemaName": "Document",
                "filter": {
                    "masterColumn": "Id",
                    "detailColumn": "Связь"
                },
            },

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

 

Ответ: в detailColumn  нужно прописать: [OrderProduct:Document:Id].Order

У меня такой же вопрос

6 комментариев
Лучший ответ
Павел, в detailColumn нужно прописать следующее выражение
detailColumn: "[OrderProduct:Order:Id].Document"

 

Вам нужно реализовать Ваш метод фильтрации, добавив свойство 'filterMethod' при объявлении детали и в методах реализовать нужную фильтрацию.

Для примера в базовой конфигурации можете посмотреть реализацию для детали Relationships в AccountPageV2.

Спасибо, думал об этом, но стало не на много легче, т.к. не очень понимаю как перевести sql запрос в формат esq.

            declare orderId = id_заказ
            
            Select d.usrName
            from usrDocument d
            join OrderProduct op on op.DocumentId = d.id
            where op.OrderId = orderId

Павел, в detailColumn нужно прописать следующее выражение
detailColumn: "[OrderProduct:Order:Id].Document"

 

Трефилов Павел Сергеевич,

Выше Александр привел пример построения связей.

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

В данном случае решение, предложенное Александром 'более красивое' yes

Спасибо за ответ, но на самом деле правильный запрос выглядит немного иначе. Моя кореневая схема Документы, мне нужно из нее получить Id заказа через промежуточную схему ПродуктыЗаказа.

Связь строится по следующему принципу:

[Имя_присоединяемой_схемы:Имя_колонки_для_связи_присоединяемой_схемы:Имя_колонки_для_связи_текущей_схемы].Колонка_присоединяемой_схемы

Значит связь выглядит так [OrderProduct:Document:Id].Order

Видимо запрос в первом посте ввел в заблуждение Александра.

Трефилов Павел Сергеевич,

Вот в этом и заключается сила community smiley

Совместными усилиями и знаниями нашли самое подходящее решение!

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Всем доброго времени суток!

Добавляю деталь в мобильное приложение - http://prntscr.com/mx7ioh
добавлял следующим образом:
 

Terrasoft.sdk.Details.add("Activity", {
	name: "WaConsultationSubjectInVisitDetail",
	title: "WaConsultationSubjectInVisitCaption",
	model: "WaConsultationSubjectInVisit",
	parentColumnName: "Activity",
	masterColumnName: "Id",
	position: 0
});

Модуль зарегистрировал в манифесте.

так же добавил отображение грида для детали:
 

Terrasoft.sdk.GridPage.setTitle("WaConsultationSubjectInVisit", "WaConsultationSubjectInVisitGridTitle");
 
Terrasoft.sdk.GridPage.setPrimaryColumn("WaConsultationSubjectInVisit", "WaConsultationSubject");
Terrasoft.sdk.GridPage.setSubtitleColumns("WaConsultationSubjectInVisit", ["WaLoyalty","WaPotential"]);

При переходе на деталь вываливаются ошибки - http://prntscr.com/mx7jtz
Подскажите что делаю не так?
Через мастер мобильного не вариант добавлять. он рушит всю предыдущую логику что была разработана ранее.

У меня такой же вопрос

1 комментарий

Такое сообщение говорит о попытке писать в поле типа boolean неподходящее значение. Вероятно, в этой новой детали что-то не так сделали с одним из логических полей. Более точно узнать причину можно, изучив саму добавляемую деталь или посмотреть в Fiddler, какой запрос идёт к веб-сервису OData. 

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

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

У меня такой же вопрос

2 комментария
Лучший ответ

Переопределите обработчик нажатия на кнопку [+] добавления новой записи. Обычно она называется AddRecordButton. Обработчик кнопки реализуйте аналогично примера на Академии. В методе openDocumentLookup накладывайте нужные фильтры, чтобы уже добавленная запись в списке выбора не появлялась.

Как вариант сделайте свою кнопку добавить или переопределите ее обработку и вызывайте где хотите свою страничку для добавления

 

Так же для добавления можно создать свою мини карточку детали тут

Переопределите обработчик нажатия на кнопку [+] добавления новой записи. Обычно она называется AddRecordButton. Обработчик кнопки реализуйте аналогично примера на Академии. В методе openDocumentLookup накладывайте нужные фильтры, чтобы уже добавленная запись в списке выбора не появлялась.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Всем привет,

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

Попробовал прокидывать сообщение из карточки в метод init детали, и в зависимости от этого менять ProfileKey (предварительно задал свои настройки колонок с разными ключами). Работает, но проблема в том, что метод init детали не отрабатывает, когда ходишь по карточкам в Combined mode.

Кто-нибудь сталкивался с подобной задачей? В какаую сторону капать?

 

У меня такой же вопрос

4 комментария
Лучший ответ

Сталкивались,

смотри метод render() подробнее тут

Сталкивались,

смотри метод render() подробнее тут

Григорий Чех,

Спасибо за ответ. А можно немного поподробней о вашем решении? Не совсем понимаю как вы подменяете настройки грида в методе render.

Тёскин Дмитрий Валерьевич,

Это был ответ на 

о проблема в том, что метод init детали не отрабатывает, когда ходишь по карточкам в Combined mode.

Метод render отрабатывает, когда ходишь по карточкам в Combined mode. 

Григорий Чех,

Спасибо за уточнение. Метод onGridDataLoaded тоже вроде отрабатывает каждый раз, но по моему у него не тот контекст и подменить ProfileKey там не получится...

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

На странице добавлены две детали с редактируемым реестром. Создал первую и понял, что неправильно. Потом создал вторую корректно и захотел первую удалить (создавал кодом). В мастере ее удалить нельзя. Открыл конфигурацию и удалил строки из схемы раздела, а именно details и diff, касающихся этой детали. Сохранил и очистил кэш. После этого перестали отображаться детали вообще и в консоли появилась ошибка cannot read property "findPrimary". После возвращения кода детали обе появились и работают. Как убрать первую деталь? 

У меня такой же вопрос

3 комментария
Лучший ответ

Очень похоже, что как-то не так удаляете деталь со страницы. Если корректно удалить из details и diff, делать должна удалиться.

Очень похоже, что как-то не так удаляете деталь со страницы. Если корректно удалить из details и diff, делать должна удалиться.

Тёскин Дмитрий Валерьевич,

Проблема в том, что даже ошибиться негде

Вот код страницы полностью:
define("UsrConcertProgram1Page", [],
function() {
    return {
        entitySchemaName: "UsrConcertProgram",
        attributes: {
            "UsrActiveEveryday": {
                    "dataValueType": Terrasoft.DataValueType.INTEGER,
                    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    "caption": "UsrActiveEveryday",
                    "value" : "0"
                }
        },
        modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
        details: /**SCHEMA_DETAILS*/{
            "Files": {
                "schemaName": "FileDetailV2",
                "entitySchemaName": "UsrConcertProgramFile",
                "filter": {
                    "masterColumn": "Id",
                    "detailColumn": "UsrConcertProgram"
                }
            },
            "UsrPerformanceDetail": {
                "schemaName": "UsrPerformanceDetail",
                "entitySchemaName": "UsrPerformance",
                "filter": {
                    "detailColumn": "UsrConcertProgram",
                    "masterColumn": "Id"
                },
            },
            "UsrSchema1Detail660d66ee": {
                "schemaName": "UsrSchema1Detail",
                "entitySchemaName": "UsrConcertPerformance",
                "filter": {
                    "detailColumn": "UsrConcertProgram",
                    "masterColumn": "Id"
                }
            }
        }/**SCHEMA_DETAILS*/,
        businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
        methods: {
            getActiveEverydayConcerts: function() {
                var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                    rootSchemaName: "UsrConcertProgram"
                });
                
                var filterGroup = this.Terrasoft.createFilterGroup();
                
                filterGroup.logicalOperation = this.Terrasoft.LogicalOperatorType.AND;
                filterGroup.add("concertsIsActive",
                this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL, "UsrIsActive", "1"));
                filterGroup.add("performancePeriodEveryday",
                this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL,
                "UsrPerformancePeriod", "85A8C133-FF83-4290-9F69-B34EAF627F8C"));
                
                esq.filters = filterGroup;
                
                esq.getEntityCollection(function(result) {
                    if (result.success)
                    {
                        this.set("UsrActiveEveryday", result.collection.getCount());
                    }
                }, this);
            },
            maxEverydayActive: function() {
                var invalidMessage = "";
                var maxActiveEverydayConcertCount = 0;
                var activeEverydayConcertCount = this.get("UsrActiveEveryday");
                this.Terrasoft.SysSettings.querySysSettingsItem("UsrMaxEverydayActiveProgram", function(value) {
                    maxActiveEverydayConcertCount = value;
                }, this);
                
                if (this.get("UsrPerformancePeriod").value == "85A8C133-FF83-4290-9F69-B34EAF627F8C".toLowerCase() &&
                this.get("UsrIsActive") && (activeEverydayConcertCount > maxActiveEverydayConcertCount) && !this.isAddMode()) {
                    invalidMessage = "Допускается не более " + maxActiveEverydayConcertCount +
                    " активных ежедневных концертных программ.";
                }
                if(this.get("UsrPerformancePeriod").value == "85A8C133-FF83-4290-9F69-B34EAF627F8C".toLowerCase() &&
                this.get("UsrIsActive") && (activeEverydayConcertCount >= maxActiveEverydayConcertCount) && this.isAddMode()) {
                    invalidMessage = "Допускается не более " + maxActiveEverydayConcertCount +
                    " активных ежедневных концертных программ.";
                }
                return {
                    fullInvalidMessage: invalidMessage,
                    invalidMessage: invalidMessage
                };
            },
            setValidationConfig: function() {
                this.callParent(arguments);
                this.addColumnValidator("UsrIsActive", this.maxEverydayActive);
                this.addColumnValidator("UsrPerformancePeriod", this.maxEverydayActive);
            },
            onEntityInitialized: function() {
                this.callParent(arguments);
                this.getActiveEverydayConcerts();
            }
        },
        dataModels: /**SCHEMA_DATA_MODELS*/{}/**SCHEMA_DATA_MODELS*/,
        diff: /**SCHEMA_DIFF*/[
            {
                "operation": "insert",
                "name": "UsrName9ed0e254-4ab5-4862-9e79-b18e052d92ab",
                "values": {
                    "layout": {
                        "colSpan": 24,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "ProfileContainer"
                    },
                    "bindTo": "UsrName"
                },
                "parentName": "ProfileContainer",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "STRING3bea7972-86d7-4d0e-b4d7-5731d5a6a6b6",
                "values": {
                    "layout": {
                        "colSpan": 24,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1,
                        "layoutName": "ProfileContainer"
                    },
                    "bindTo": "UsrConcertCode",
                    "enabled": true
                },
                "parentName": "ProfileContainer",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "LOOKUP2c6c3d90-34b5-4a43-9b28-26c5c29c6c48",
                "values": {
                    "layout": {
                        "colSpan": 24,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 2,
                        "layoutName": "ProfileContainer"
                    },
                    "bindTo": "UsrOwner",
                    "enabled": true,
                    "contentType": 3
                },
                "parentName": "ProfileContainer",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "UsrIsActive3354c9f0-c35f-4c7c-85ec-0b3cc01376b8",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Header"
                    },
                    "bindTo": "UsrIsActive"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "CreatedOn770eb82e-0b06-4f93-be35-bdd0ddac28b8",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 12,
                        "row": 0,
                        "layoutName": "Header"
                    },
                    "bindTo": "CreatedOn"
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "UsrActiveEveryday",
                "values": {
                    "bindTo": "getActiveEverydayConcerts",
                    "caption": "UsrActiveEveryday",
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1
                    }
                },
                "parentName": "Header",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "Tab75eff25dTabLabel",
                "values": {
                    "caption": {
                        "bindTo": "Resources.Strings.Tab75eff25dTabLabelTabCaption"
                    },
                    "items": []
                },
                "parentName": "Tabs",
                "propertyName": "tabs",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "Tab75eff25dTabLabelGroup46c8d52b",
                "values": {
                    "caption": {
                        "bindTo": "Resources.Strings.Tab75eff25dTabLabelGroup46c8d52bGroupCaption"
                    },
                    "itemType": 15,
                    "markerValue": "added-group",
                    "items": []
                },
                "parentName": "Tab75eff25dTabLabel",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "values": {
                    "itemType": 0,
                    "items": []
                },
                "parentName": "Tab75eff25dTabLabelGroup46c8d52b",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrTeama25e968a-f7f0-4c80-bde3-ed860af75538",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 0,
                        "layoutName": "Tab75eff25dTabLabelGridLayoutd14f72b6"
                    },
                    "bindTo": "UsrTeam"
                },
                "parentName": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrComment8c10205e-2bf8-42d0-b7fa-605cc32a37af",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 2,
                        "column": 12,
                        "row": 0,
                        "layoutName": "Tab75eff25dTabLabelGridLayoutd14f72b6"
                    },
                    "bindTo": "UsrComment",
                    "enabled": true,
                    "contentType": 0,
                    "labelConfig": {
                        "caption": {
                            "bindTo": "Resources.Strings.UsrComment8c10205e2bf842d0b7fa605cc32a37afLabelCaption"
                        }
                    }
                },
                "parentName": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "UsrPerformancePeriod8fdfacd0-81ef-4bf3-9ccc-4cb9ab0f5b7b",
                "values": {
                    "layout": {
                        "colSpan": 12,
                        "rowSpan": 1,
                        "column": 0,
                        "row": 1,
                        "layoutName": "Tab75eff25dTabLabelGridLayoutd14f72b6"
                    },
                    "bindTo": "UsrPerformancePeriod",
                    "enabled": true,
                    "contentType": 5
                },
                "parentName": "Tab75eff25dTabLabelGridLayoutd14f72b6",
                "propertyName": "items",
                "index": 2
            },
            {
                "operation": "insert",
                "name": "UsrSchema1Detail660d66ee",
                "values": {
                    "itemType": 2,
                    "markerValue": "added-detail"
                },
                "parentName": "TabsContainer",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "NotesAndFilesTab",
                "values": {
                    "caption": {
                        "bindTo": "Resources.Strings.NotesAndFilesTabCaption"
                    },
                    "items": []
                },
                "parentName": "Tabs",
                "propertyName": "tabs",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "Files",
                "values": {
                    "itemType": 2
                },
                "parentName": "NotesAndFilesTab",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "NotesControlGroup",
                "values": {
                    "itemType": 15,
                    "caption": {
                        "bindTo": "Resources.Strings.NotesGroupCaption"
                    },
                    "items": []
                },
                "parentName": "NotesAndFilesTab",
                "propertyName": "items",
                "index": 1
            },
            {
                "operation": "insert",
                "name": "Notes",
                "values": {
                    "bindTo": "UsrNotes",
                    "dataValueType": 1,
                    "contentType": 4,
                    "layout": {
                        "column": 0,
                        "row": 0,
                        "colSpan": 24
                    },
                    "labelConfig": {
                        "visible": false
                    },
                    "controlConfig": {
                        "imageLoaded": {
                            "bindTo": "insertImagesToNotes"
                        },
                        "images": {
                            "bindTo": "NotesImagesCollection"
                        }
                    }
                },
                "parentName": "NotesControlGroup",
                "propertyName": "items",
                "index": 0
            },
            {
                "operation": "insert",
                "name": "UsrPerformanceDetail",
                "values": {
                    "itemType": 2,
                    "markerValue": "added-detail"
                },
                //"parentName": "TabsContainer",
                "propertyName": "items",
                "index": 2
            }
        ]/**SCHEMA_DIFF*/
    };
});

 

Удаляю я все с деталью UsrPerformanceDetail

 

Можно подойти к решению с другой стороны: откатиться до стандартной страницы из «коробки» без обеих деталей, затем добавить вторую.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Добрый день, коллеги.

Преамбула.

Есть раздел Доп соглашение, на странице редактирования есть деталь Дочернее доп соглашение, которая берется с этого же раздела. Есть поле Основное доп соглашение, которое заполняется при добавлении дочернего доп соглашения. Между страницей редактирования и деталью настроен обмен сообщениями (message) реагирующими на изменение поля Основное доп соглашение, если поле заполнено - кнопка добавления записей невидима, если поле пустое - видима. 

Собственно проблема.

При добавлении записи в деталь (нажатии на "+") открывается карточка редактирования этого же раздела и в поле Основное доп соглашение проставляется ссылка на родителя, НО сообщение о заполнении поля не отправляется на деталь и соответственно кнопка добавления записи остаётся видима.

Насколько я понял это происходит из-за того что фактически текущей страницей является родительская (с которой нажали кнопку добавления записи). Может кто-нибудь знает как можно передать сообщение с открывшейся карточки добавления записи на её деталь для того что бы скрыть кнопку добавления записи и отменить создание "матрёшки" (дочка в дочке в дочке в дочке и т.п.)

У меня такой же вопрос

5 комментариев
Лучший ответ

На onEntityInitialized вызовите функцию которая обрабатывает изменение поля Основное доп соглашение и отправляет сообщение в деталь.

Игорь, добрый день! После добавления записи с карточки детали, сама запись отображается в детали на форме? Так же, запись существует в таблице БД?

На onEntityInitialized вызовите функцию которая обрабатывает изменение поля Основное доп соглашение и отправляет сообщение в деталь.

engineer7,

Добрый день. Сама запись на форме отображается и в БД существует.

Есть карточка детали(то есть та же карточка что и родитель) и есть схема детали, вы передаете на деталь сообщение? на детале ведь та кнопка добавить

Радчук Виталий Владимирович,

Да, именно так.

Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Коллеги доброго времени суток!

Реализовал деталь с редактируемым реестром и карточкой редактирования записи код ниже:

define("AbAccountProductDetail",
	["ConfigurationEnums", "ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
	function (enums) {
		return {
			entitySchemaName: "AbAccountProduct",
			attributes: {
				"IsEditable": {
					dataValueType: Terrasoft.DataValueType.BOOLEAN,
					type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
					value: true
				}
			},
			mixins: {
				ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
			},
			methods:{
				init: function() {
					this.callParent(arguments);
					this.sandbox.subscribe("[AbAccountProductEntityEventListner]:[RequestToPlatform]:[Exception]", this.accountProductEntityListnerMsgHandler, this);
				},
 
				/*Overrided "BaseGridDetailV2"*/
				editRecord: function(record) {
					var activeRow = record || this.getActiveRow();
					if (!activeRow) {
						return;
					}
					if (!this.getIsCardValid()) {
						return;
					}
					var isCardChanged = this.getIsCardChanged();
					var primaryColumnValue = typeof activeRow === "object" ? activeRow.get(activeRow.primaryColumnName) : activeRow;
					var typeColumnValue = this.getTypeColumnValue(activeRow);
					this.setLastActiveRow(primaryColumnValue);
					if (isCardChanged) {
						this.set("CardState", enums.CardStateV2.EDIT);
						this.set("EditPageUId", typeColumnValue);
						this.set("PrimaryValueUId", primaryColumnValue);
						var args = {
							isSilent: true,
							messageTags: [this.sandbox.id]
						};
						this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
					} else {
						this.openCard(enums.CardStateV2.EDIT, typeColumnValue, primaryColumnValue);
					}
				},
 
				accountProductEntityListnerMsgHandler: function() {
					Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
					function(scope, message){
							if (!message || message.Header.Sender !== "[AbAccountProductEntityEventListner]:[RequestToPlatform]:[Exception]") {
							return;
						}
						var message2 = message.Body;
						if (!this.Ext.isEmpty(message2)) {
							window.console.info(message2);
							this.Terrasoft.showInformation(message2);
						}
					}, this);
				}
			},
			diff: [
				{
					"operation": "merge",
					"name": "DataGrid",
					"values": {
						"className": "Terrasoft.ConfigurationGrid",
						"generator": "ConfigurationGridGenerator.generatePartial",
						"generateControlsConfig": { "bindTo": "generateActiveRowControlsConfig" },
						"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": "card",
								"markerValue": "card",
								"imageConfig": { "bindTo": "Resources.Images.CardIcon" }
							},
							{
								"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
					}
				}
			]
		};
	});

Пришлось переопределить editRecord():
 

var primaryColumnValue = typeof activeRow === "object" ? activeRow.get(activeRow.primaryColumnName) : activeRow;

т.к. дальше не срабатывало.
сейчас работает - http://prntscr.com/lfe61n
но при переходе на страницу редактирования поле для связи не заполняется - http://prntscr.com/lfe6k4
Подскажите в чем может быть дело?
Заранее благодарен.

У меня такой же вопрос

2 комментария
Лучший ответ

Попробуйте например вызывать openCardInChain и передавать туда значения по умолчанию
 

addChildRecord: function(typeColumnValue, date) {
var selectedItem = this.get("ActiveRow");
var defaultValues = [];
defaultValues.push({
	name: "ParentId",
	value: typeColumnValue
});
defaultValues.push({
	name: "UsrDate",
	value: date
});
var config = {
	sandbox: this.sandbox,
	schemaName: this.getEditPageSchemaName(typeColumnValue),
	operation: ConfigurationEnums.CardStateV2.ADD,
	moduleId: this.getChainCardModuleSandboxId(typeColumnValue),
	defaultValues: defaultValues
};
this.openCardInChain(config);
},

 

По идее, страница редактирования берёт значения полей из базы. То есть, перед открытием карточки редактируемый реестр должен сохранить запись. Видимо, у Вас такого не происходит.

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

Попробуйте например вызывать openCardInChain и передавать туда значения по умолчанию
 

addChildRecord: function(typeColumnValue, date) {
var selectedItem = this.get("ActiveRow");
var defaultValues = [];
defaultValues.push({
	name: "ParentId",
	value: typeColumnValue
});
defaultValues.push({
	name: "UsrDate",
	value: date
});
var config = {
	sandbox: this.sandbox,
	schemaName: this.getEditPageSchemaName(typeColumnValue),
	operation: ConfigurationEnums.CardStateV2.ADD,
	moduleId: this.getChainCardModuleSandboxId(typeColumnValue),
	defaultValues: defaultValues
};
this.openCardInChain(config);
},

 

Войдите или зарегистрируйтесь, чтобы комментировать