Асинхронность при доступе в БД для чтения системной настройки и данных
Cделан запрос в базу данных из клиентского модуля для получения системной настройки:
this.Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(value) {
countSettings = value;
}, this);Получены данные из БД отфильтровав их и сравнив с полученным значением из системной настройки ранее, и если значение выпадающего списка periodicity равно "Ежедневно" и количество записей в базе больше чем системной настройке - срабатывает валидация на поле и всплывающее уведомление при попытке сохранения:
message - сообщение для поля валидации;
periodicity - выпадающий список (словарь) в котором есть значение "Ежедневно";
countSettings - ранее полученное значение системной настройки;
concertProgramsCount - количество записей в таблице;
var periodicity = "";
if (this.get("PsPeriodicity")) {
periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "PsConcertPrograms"
});
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
var esq1Filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
"PsPeriodicity.Name", "Ежедневно");
esq.filters.add("esq1Filter", esq1Filter);
esq.getEntityCollection(function(result) {
var message = "";
if (result.success) {
var concertProgramsCount = result.collection.collection.length;
if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
}
}
return message;
}, this);Вывод валидации для поля и при сохранении страницы:
concertHallsValidator: function(message) {
var invalidMessage = message;
return {
fullInvalidMessage: invalidMessage,
invalidMessage: invalidMessage
};
}Проблема в том что по отдельности все работает, но когда вместе - вступает в дело асинхронность и все идет не по очереди, а если использую через callback тогда застреваю на замыкании.
Спасибо всем кто окажет помощь в решении проблемы.
Нравится
Prime Source,
нет. стоп. я думал вы прогоняете esq в onEntityInitialized, а потом используете this.$PeriodValidationMessage для проверки. тогда такие варианты:
1) на изменение поля PsPeriodicity запускаете concertHallsValidator. Изменяете this.addColumnValidator("CreatedOn", this.MessageValidator);
2) Используете asyncValidate (вроде так называется метод)
И уберите return. Ну не используется он в асинхронных функциях)
немного не понимаю смысла return из async функции, поэтому вариант такой:
в attributes добавляете
"PeriodValidationMessage": {
dataValueType: 1,
value: ""
}esq:
var periodicity = "";
if (this.get("PsPeriodicity")) {
periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "PsPeriodicity.Name", "Ежедневно"));
esq.getEntityCollection(function(result) {
if (result.success) {
var concertProgramsCount = result.collection.collection.length;
//считывание сист. настройки
Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
//сравнение
if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
this.$PeriodValidationMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
}
}, this);
}
}, this);валидация
concertHallsValidator: function(message) {
var invalidMessage = this.$PeriodValidationMessage;
return {
fullInvalidMessage: invalidMessage,
invalidMessage: invalidMessage
};
}
Добрый день,
Каждый борется с асинхронностью своими средствами :)
Как вариант, можно вложить одно в другое: выполнять запросы по очереди, по мере получения ответа из БД. Например перенести вашу логику с esq запросом в колбэк системной настройки.
Тёскин Дмитрий Валерьевич,
Пробовал, тогда return возвращает поздно ответ
concertHallsValidator: function(){
var periodicity = "";
if (this.get("PsPeriodicity")) {
periodicity = this.get("PsPeriodicity").displayValue;
}
this.Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: "PsConcertPrograms"
});
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
var esq1Filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
"PsPeriodicity.Name", "Ежедневно");
esq.filters.add("esq1Filter", esq1Filter);
esq.getEntityCollection(function(result) {
var invalidMessage = "";
if (result.success) {
var concertProgramsCount = result.collection.collection.length;
if (periodicity === "Ежедневно" && concertProgramsCount > countSettings ) {
invalidMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
}
}
return invalidMessage;
}, this);
}, this);
},
setValidationConfig: function() {
this.callParent(arguments);
this.addColumnValidator("PsPeriodicity", this.concertHallsValidator);
}
Варфоломеев Данила,
Асинхронность не дает
methods: {
concertHallsValidator: function(callback){
var periodicity = "";
if (this.get("PsPeriodicity")) {
periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "PsPeriodicity.Name", "Ежедневно"));
esq.getEntityCollection(function(result) {
if (result.success) {
var concertProgramsCount = result.collection.collection.length;
//считывание сист. настройки
Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
//сравнение
if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
this.$PeriodValidationMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
}
return callback.call(this);
}, this);
}
}, this);
},
MessageValidator: function() {
var invalidMessage = this.$PeriodValidationMessage;
return {
fullInvalidMessage: invalidMessage,
invalidMessage: invalidMessage
};
},
setValidationConfig: function() {
// Вызывает инициализацию валидаторов родительской модели представления.
this.callParent(arguments);
this.addColumnValidator("CreatedOn", this.concertHallsValidator(this.MessageValidator));
}
},
}
Prime Source,
нет. стоп. я думал вы прогоняете esq в onEntityInitialized, а потом используете this.$PeriodValidationMessage для проверки. тогда такие варианты:
1) на изменение поля PsPeriodicity запускаете concertHallsValidator. Изменяете this.addColumnValidator("CreatedOn", this.MessageValidator);
2) Используете asyncValidate (вроде так называется метод)
И уберите return. Ну не используется он в асинхронных функциях)
Варфоломеев Данила,
Спасибо большее, помогло отлично asyncValidate. Раньше не знал что этот метод. Вод такой код заработал отлично:
asyncValidate: function(callback, scope) {
this.callParent([function(response) {
if (!this.validateResponse(response)) {
return;
}
Terrasoft.chain(
function(next) {
this.validateConcertHalls(function(response) {
if (this.validateResponse(response)) {
next();
}
}, this);
},
function(next) {
callback.call(scope, response);
next();
}, this);
}, this]);
},
validateConcertHalls: function(callback, scope) {
Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
var periodicity = "";
var result = {success: true};
if (this.get("PsPeriodicity")) {
periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
"PsPeriodicity.Name", "Ежедневно"));
esq.getEntityCollection(function(response) {
if (response.success && periodicity === "Ежедневно" && (!this.isAddMode() &&
response.collection.getCount() > countSettings) || (this.isAddMode() &&
response.collection.getCount() >= countSettings)) {
result.message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
result.success = false;
}
callback.call(scope || this, result);
}, this);
}, this);
}
Prime Source,
Если ваша функция должна возвращать какие-то значение, то из коллбэка это сделать не получится. В этом случае у вас уже должны быть где-то готовые значения для того, что бы функция валидации могла синхронно выполниться и вернуть значения. Например значение системной настройки можно получить при инициализации страницы и сохранить в атрибуте страницы, т.к. системная настройка скорее всего не будет часто меняться. Значение из esq запроса можно так же получить раньше и сохранить в атрибут, а потом уже при валидации оперировать существующими значениями. Ну или сделать так, как посоветовал Варфоломеев Данила.