Добрый день!
Есть такой метод
calcCountRec: function() {
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "UsrProductInActivity"
});
esq.addAggregationSchemaColumn("Id",
Terrasoft.AggregationType.COUNT, "UsrProductInActivityCount");
esq.filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "UsrActivity", this.get("UsrActivity").value));
esq.getEntityCollection(function(response) {
if (response.success) {
var collection = response.collection;
if (collection) {
this.set("CountRec", collection.getByIndex(0).get("UsrProductInActivityCount"));
}
}
}, this);
},
где CountRec - это виртуальный атрибут
"CountRec": {
"type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
"dataValueType": this.Terrasoft.DataValueType.FLOAT
}
Необходимо при сохранении записи в методе save написать некие проверки, в которых было бы задействовано значение рассчитанного атрибута CountRec
Подскажите, где и как можно вызвать метод calcCountRec, чтобы значение CountRec не было undefined ? (может быть надо как-то сам метод изменить?)
если в save вызвать, и потом в save проверки - то значение undefined
если в onEntityInitialized вызвать, а потом в save проверки - то значение undefined
Нравится
Можно вообще всё вычислять без арибута прямо в методе сохранения. Или сделать обычное поле и заполнять значением суммы при сохранении записи на детали продуктов при помощи БП или триггера.
Зверев Александр,
Обычное поле не нужно, на самом деле таких атрибутов несколько.
А как можно вычислить без атрибута прямо в методе сохранения?
Так же само, как сейчас вычисляете внутри функции. Но зачем каждый раз вычислять сумму, если можно сделать поле и хранить в нём.
Зверев Александр,
Это одно из вычислений(просто пример вычисления)
Есть второе вычисление - в другом методе
calcCurrencyIdFromActivity: function() {
var activityId = this.get("UsrActivity");
if (activityId) {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "Activity"
});
esq.addColumn("Id");
esq.addColumn("UsrCurrency.Id", "CurrencyActivity");
esq.filters.add("ActivityId", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Id", activityId.value));
esq.getEntityCollection(function(response) {
if (response && response.success) {
if (!response.collection.isEmpty()) {
var result = response.collection.getItems()[0];
this.set("CurrencyIdActivity", result.get("CurrencyActivity"));
}
}
}, this);
}
}
В результате вызова этих двух методов должны получиться значения у двух виртуальных атрибутов. Должны быть некие проверки, зависящие от совокупности значений двух виртуальных атрибутов - в методе сохранения.
типа if this.get("CurrencyIdActivity").value==.. && this.get("CountRec").value
Но если вызывать эти функции, а потом посмотреть значения этих атрибутов, то они undefined, соответственно проверку выполнить невозможно.
Точно так же можете записать эти значения в две локальные переменные внутри функции, вызываемой при сохранении, и работать с ними.
Зверев Александр,
то есть те же самые 2 метода,вызвать их в методе save, но внутри методов вместо записи в виртуальные атрибуты запись в локальную переменную?
то есть вместо, например,
this.set("CountRec", сollection.getByIndex(0).get("UsrProductInActivityCount"));
будет
var cc= сollection.getByIndex(0).get("UsrProductInActivityCount"))
И в каждом методе будет своя локальная переменная,но они же локальные будут (поэтому атрибуты-то и делались, чтобы можно было с ними работать на выходе..), нужен для условия результат как первого метода и второго метода, и если условие будет не соблюдено,то выводится сообщение при сохранении.
Или вы имеете ввиду объединить 2 метода в один как-то?
Если поле будет вычисляемым, то оно всё равно должно будет заново подсчитать количество и посылать запрос в базу при каждом обращении. Если записать в поле таблицы, то подсчитывать количество нужно будет только при добавлении или удалении записи на деталь.
Зверев Александр,
Его не надо записывать в таблицу, подсчет количества был просто в качестве примера. Например, при сохранении карточки "Продукты в активности" нужно вычислить(получить) значение поля Валюта из Активности, а еще получить значение любого другого связанного поля из другой связанной таблицы(не важно, например, должность контакта). Вопрос-то же.. не в этом был изначально.. Вопрос был в том как работать с результатом метода...Может быть можно как-то переделать сам метод, чтобы после его выполнения получить значение на выходе, и работать с ним дальше?..
Можно записать просто в локальную переменную внутри обработчика сохранения. Для удобства вызова написать функцию, которая получает на вход нужные Id и возвращает по ним значение из таблиц базы.
Да, спасибо большое. Мой вопрос как раз состоял в том, как должна выглядеть подобная функция, чтобы она возвращала рассчитанное значение? Не могли бы вы привести пример? Заранее спасибо.
Функция нижеприведенная, к сожалению, не может вернуть ни значения currencyActivity, ни значения sumQuantity, ни значения сс, потому что все эти переменные существуют только в рамках esq.getEntityCollection(function(response) {...}
calcCheckCurrency: function() {
var activityId = this.get("UsrActivity");
if (activityId) {
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "Activity"
});
esq.addColumn("Id");
esq.addColumn("UsrCurrency.Id", "CurrencyActivity");
esq.addColumn("UsrSumQuantity","SumQuantity");
esq.filters.add("ActivityId", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Id", activityId.value));
esq.getEntityCollection(function(response) {
if (response && response.success) {
if (!response.collection.isEmpty()) {
var result = response.collection.getItems()[0];
var currencyActivity=result.get("CurrencyActivity");
var sumQuantity=result.get("SumQuantity");
if ((currencyActivity !==this.get("UsrCurrency").value) &&
(
((this.isAddMode() || this.isCopyMode()) && (sumQuantity>=1))
||
((this.isEditMode()) && (sumQuantity>1))
)
)
{
var cc=1;
//this.showInformationDialog("Валюта не совпадает //с ранее выбранной");
}
}
}
}, this);
}
},
В таком случае можно всю логику реализовать тоже внутри функции, которая вызывается по завершению getEntityCollection.
Добрый день! Внутри это где? Не поняла вас.
Проблема-то как раз в том, что асинхронно работает, и после завершения getEntityCollection не доступны данные там вычисленные, они undefined.
Нужно, если условие не выполняется (условие проверяется внутри getEntityCollection), то выводить предупреждение и не сохранять карточку. Если выполняется, то сохранять карточку.
О методе save написан текст вышеприведенный, условие проверяется внутри getEntityCollection, предупреждение выводится - все прекрасно. Но не понятно, как вызвать здесь родительское стандартное сохранение
Если написать так:
if ((currencyActivity !==this.get("UsrCurrency").value) &&
(
((this.isAddMode() || this.isCopyMode()) && (sumQuantity>=1))
||
((this.isEditMode()) && (sumQuantity>1))
)
)
{
var cc=1;
this.showInformationDialog("Валюта не совпадает с ранее выбранной");
}
else this.callParent(arguments);
то возникает ошибка (Cannot read property 'superclass' of undefined)
Если this.callParent(arguments) поставить в методе save в конце всей вышеприведенной функции, то тогда предупреждение выводится, но и сохранение также происходит ( а надо, чтобы не происходило)
Зверев Александр,
Спасибо, помогла связанная тема
https://community.terrasoft.ru/questions/pereopredelenie-metoda-save-pr…