Добрый день.
Я добавил в конфигурацию два раздела "Складские документы" и "Размещения". В объекте и карточке раздела "Складские документы" имеется поле "Склад", которое ссылается на объект раздела "Размещения". В объекте раздела "Размещения" есть логическое поле "Значение по умолчанию", которое должно принимать значение true только для одной записи в разделе.
Задача заключается в том, чтобы разобраться как в схеме модели представления карточки запрограммировать логику, по которой в страничку редактирования будет подставляться значение по умолчанию из раздела "Размещения".
Суппорт почему-то предложил мне инициализировать значением этого поле во встроенном процессе объекта "Складские документы" ( :) вероятно тот кто мне отвечал забыл, что у объекта нет события уровня инициализации объекта ).
Я попытался сам решить проблему. Но поскольку я не очень хорошо знаю объекты bpmonline, а документации по кодированию клиентской части просто нет, то есть причины сомневаться в оптимальности моего кода.
Вот решение:
if (this.isAddMode() || this.isCopyMode()) {
this.getIncrementCode(function(responce) {
this.set("NxrName", responce);
});
}
//Создаем запрос
var select = Ext.create( "Terrasoft.EntitySchemaQuery", {rootSchemaName: "NxrStore"} );
//Добавляем в запрос поля
select.addColumn("Id");
select.addColumn("NxrName");
select.addColumn("NxrIsDefault");
//Настраиваем фильт
select.filters.addItem(select.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "NxrIsDefault", true));
// Используем стандартную функцию обратного вызова для заполнения поля NxrStore
select.getEntityCollection(function(response) {
if (response && response.success) {
var defaultStore =
{
value : response.collection.collection.items[0].values.Id,
displayValue : response.collection.collection.items[0].values.NxrName
}
this.set("NxrStore", defaultStore);
}
}, this);
this.callParent(arguments);
}
Из "волнующих" моментов выделю два ( хотя думаю их больше ;) )
1. Правильно ли выбран обработчик onEntityInitialized
2. Правильно ли я сделал, что создал defaultStore для имитации вставки NxrStore (почти уверен что можно более просто реализовать).
3. Нужен ли в данном случае this.callParent(arguments) и для чего он нужен вообще :)?
Нравится
Геннадий, здравствуйте!
Отвечу по порядку:
1. Да, выбран корректно.
2. Правильно сделали. Но хотелось бы отметить следующее, что Вы не совсем правильно используете работу с коллекцией. Т.е. написано правильно, но логично работу с коллекцией выполнять примерно так:
[javascript]
select.getEntityCollection(function(response) {
if (response && response.success) {
var collection = response.collection;
if (collection && collection.getCount() > 0) {
var store = collection.getByIndex(0);
var defaultStore = {
value : store.get("Id"),
displayValue : store.get("NxrName")
};
this.set("NxrStore", defaultStore);
}
}
}, this);
[/javascript]
3. Правильно. СallParent используется для вызова метода родительских объектов. И если Вы хотите, чтобы маска загрузки проходила быстрее, т.е. скрывалась, то нужно callParent ставить в самом начале.
Добрый день, Дмитрий!
Спасибо за ваши замечания по коду.
Сегодня я получил ответ от ТП и в результате "компиляции" вашего примера и примера от ТП получил результирующий код:
[javascript]
setEntityDefaultValues: function(callback, scope) {
this.callParent(arguments);
if (this.isAddMode() || this.isCopyMode()) {
this.getIncrementCode(function(responce) {
this.set("NxrName", responce);
});
}
var self = this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
var esq_NxrStore = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "NxrStore" });
esq_NxrStore.addColumn("Id");
esq_NxrStore.filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "NxrIsDefault", true));
esq_NxrStore.getEntityCollection(function(response) {
if (response.success) {
var collection = response.collection;
if (collection.getCount() > 0 && (this.isAddMode() || this.isCopyMode())) {
var store = collection.getByIndex(0);
var storeId = store[0].get("Id");
if (this.Terrasoft.isGUID(storeId)) {
this.loadLookupDisplayValue("Account", accountId);
}
}
self.apply(scope || this, [callback, scope || this]);
}
}, this);
}
[/javascript]
В принципе мне все понятно, кроме назначения строк:
1. var self = this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
2. self.apply(scope || this, [callback, scope || this]);
Геннадий, при использовании
[javascript]
var self = this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
self.apply(scope || this, [callback, scope || this]);
[/javascript]
вызивать this.callParent(arguments); не нужно. Это уже происходит во второй строке.
Данная конструкция реализует своего рода «замыкание». Это необходимо для того, чтоб поле заполнялось сразу, а не спустя некоторое время. Данное поведение связано с ассинхронностью вызовов встроенных функций.
Первая строка – ссылка на метод родителя.
Вторая строка – замыкание внутри функции и вызов замещенного метода родителя.
Спасибо, Дмитрий!
Хочу отметить, что в коде ошибка копипаста :)
[javascript]
var storeId = store[0].get("Id");
[/javascript]
*[javascript]
var storeId = store.get("Id");
[/javascript]
Дмитрий, я убрал
[javascript]
this.callParent(arguments);
[/javascript]
а в консоль стала выводится строка: Cannot read property 'apply' of undefined
Вот код:
[javascript]
setEntityDefaultValues: function(callback, scope) {
//this.callParent(arguments);
if (this.isAddMode() || this.isCopyMode()) {
this.getIncrementCode(function(responce) {
this.set("NxrName", responce);
});
}
var self = this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
var esq_NxrStore = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "NxrStore" });
esq_NxrStore.addColumn("Id");
esq_NxrStore.filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "NxrIsDefault", true));
esq_NxrStore.getEntityCollection(function(response) {
if (response.success) {
var collection = response.collection;
if (collection.getCount() > 0 && (this.isAddMode() || this.isCopyMode())) {
var store = collection.getByIndex(0);
var storeId = store.get("Id");
if (this.Terrasoft.isGUID(storeId)) {
this.loadLookupDisplayValue("NxrStore", storeId);
}
}
self.apply(scope || this, [callback, scope || this]);
}
}, this);
}
[/javascript]
если строку //this.callParent(arguments); раскоментировать, то карточка грузится мгновенно и никаких ошибок нет.
Попробуйте, пожалуйста, сделать наоборот, оставить callParent, а убрать
[csharp]
var self =this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
self.apply(scope || this, [callback, scope || this]);
[/csharp]
Если сделать так как вы сказали, то ошибки нет и страничка загружается быстро.