Добрый день

 

Поставлена задача контролировать статус активностей по обращению на момент перехода в статус "IsResolved". Сделал на CasePage в methods 2 функции:

asyncValidate: function(callback, scope) {
	this.callParent([function(response) {
		if (!this.validateResponse(response)) {
			return;
		}
		Terrasoft.chain(
			function(next) {
				this.validateActivities(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function() {
				callback.call(scope, response);
			}, this);
	}, this]);
},
validateActivities: function(callback, scope) {
	var result = {success: true};
	if (this.get("Status").IsResolved===true) {
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "Activity" });
		esq.addColumn("Status.Finish", "Isfinished");
		esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
			"Status.Finish", "0"));
		esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
			"Case", this.get("Id")));
		esq.getEntityCollection(function(response) {
			if (response.success && response.collection.getCount() > 0) {
					result.message = this.get("Resources.Strings.CantChangaStatus");
					result.success = false;
			}
			callback.call(scope || this, result);
		}, this);
	}
}

Если обращение существует, то все отлично. Проверка идет, сохранять обращение не дает.

Возникла проблема с созданием обращения. Все намертво подвисает и ошибок в логах нет. Подскажите куда копать

Нравится

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

Алексей, не пробовали отладку в этом коде и просмотр уходящих к серверу HTTP-запросов. Зависание может означать или цикл, или рекурсию, когда эта логика будет повторяться снова и снова.

 

А если заменить проверку с ESQ на заглушку, тоже зависает? Может, дело в асинхронности получения ответа от него, а выполнение проверки в asyncValidate ожидало результата сразу?

 

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

Показать все комментарии

Всем доброго времени! Есть вопрос на примере простенького процесса:

 

Если пользователь выбирает вариант:

"Отлично" - шаг должен завершится без обязательного заполнения поля "комментарий".

"Плохо" - шаг должен завершится с обязательным заполнением поля "комментарий".

 

Как проще реализовать проверку факта заполнения поля в зависимости от нажатой кнопки?

 

Нравится

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

Сделайте поле "Комментарий" обязательным

И при кнопке "Хорошо" уберите проверку обязательности

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Сделайте поле "Комментарий" обязательным

И при кнопке "Хорошо" уберите проверку обязательности

t.ponomarov,

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

Владимир Соколов,

спасибо, как то не сообразил за эту функцию. 

 

Если в один элемент, то только через преднастроенную страницу.

Показать все комментарии

Здравствуйте. Задача была в валидации по полю и системной настройке. Читал статьи по фильтрам в ESQ и по форуму перелистал всё.

Всё работает, кроме одного момента.

 

Валидация:

Если значение выпадающего списка frequency равно "Ежедневно" и в выпадающем списке active поле = "Да" и количество записей в базе больше чем системной настройке(в данном случае 5) - срабатывает валидация на поле и всплывающее уведомление при попытке сохранения, или изменения записи.

 

frequency - выпадающий список периодичностей;

active - выпадающий список активности;

ermsg - сообщение ошибки;

maxCount - системная настройка (ранее "MaxAmountofDailyActivities");

response.collection.getCount() - актуальное кол-во записей;

 

При сохранении записи с полем "Ежедневно" + "Да", если таких записей уже 5  - валидация работает и правильно выдаёт ошибку. 

1.Но если любую другую запись, например с полем "Еженедельно" + "Да" изменить на "Ежедневно" + "Да", то ошибка не показывается и запись сохраняется. В данный момент записей становится уже 6.

2.Но если далее создавать записи с "Ежедневно" + "Да" или изменять другие на "Ежедневно" + "Да", ошибка показывается и всё продолжает работать нормально.

код метода прикрепил ниже + скриншоты 

 

methods: {
	asyncValidate: function(callback, scope) {
		this.callParent([function(response) {
			if (!this.validateResponse(response)) {
				return;
			}
			Terrasoft.chain(
				function(next) {
					this.validateSwimmingPrograms(function(response) {
						if (this.validateResponse(response)) {
							next();
						}
					}, this);
				},
				function(next) {
					callback.call(scope, response);
					next();
				}, this);
		}, this]);
	},
	validateSwimmingPrograms: function(callback, scope) {
		Terrasoft.SysSettings.querySysSettingsItem("MaxAmountofDailyActivities", function(maxCount) {
			var frequency = "";
			var active = "";
			var ermsg = this.get("Resources.Strings.ErrorMessage");
			var result = {success: true};
			if (this.get("UsrFrequency")) {
				frequency = this.get("UsrFrequency").displayValue;
			}
			if (this.get("UsrActive")) {
				active = this.get("UsrActive").displayValue;
			}
			var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "UsrSwimmingPrograms" });
			esq.addColumn("UsrFrequency.Name", "UsrFrequencyName");
			esq.addColumn("UsrActive.Name", "UsrActiveName");
			esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
				"UsrFrequency.Name", "Ежедневно"));
			esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
				"UsrActive.Name", "Да"));
			esq.getEntityCollection(function(response) {
				if (response.success && frequency === "Еженедельно" || frequency === "Ежемесячно" ||
					frequency === "Ежедневно" && active === "Нет"){
					result.success = true;
				}
				else if (response.success && frequency === "Ежедневно" && active === "Да" && (!this.isAddMode() && 
					response.collection.getCount() > maxCount) || (this.isAddMode() && 
					response.collection.getCount() >= maxCount)) {
						result.message = maxCount + ermsg + active;
						result.success = false;
				}
				callback.call(scope || this, result);
			}, this);
		}, this);
	}
},

Ниже по очереди: 

- Уже созданные 5 записей;

- при создании 6-ой с "Ежедневно" + "Да" выдаёт ошибку(выводит системную настройку(5), и в конце активность;

- При создании другой записи с другиме полями - ошибку не выводит(как и надо);

- При смене в пред. записи поля на "Ежедневно" - сохраняет (должно выводить ошибку);

- При последующих сохранения изменения записей всё работает корректно(где надо выдаёт ошибку, где не надо - не выдёт).

Нравится

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

То есть Ваша функция не вызывается при изменении существующей записи, а только для новых? Проверьте, выполняется ли вообще перед сохранением функция, добавленная в asyncValidate и доходит ли до вызова validateSwimmingPrograms. 

 

Правильные примеры валидации есть в этой теме  и в DocumentPageV2 пакета Document в «коробке»:

asyncValidate: function(callback, scope) {
	this.callParent([function(response) {
		if (!this.validateResponse(response)) {
			return;
		}
		Terrasoft.chain(
			function(next) {
				this.validateAccountOrContactFilling(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function(next) {
				this.validateUniqueNumber(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function(next) {
				callback.call(scope, response);
				next();
			}, this);
	}, this]);
},

 

Василий, попробуйте в браузере поставить отладчик и пошагово посмотреть, как выполняется эта функция. Заходит ли вообще в неё, правильно считает количество? Может, меняемая запись не учитывается, поскольку проверка идёт по последней ветке с «>=»?

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

Зверев Александр,

Поставил отладчик, показывает только одно предупреждение при входе в карточку. 

В разделе Активности ничего не делал, не пойму почему ругается на это.

Названия справочных полей заменю на id полей, пока для вида оставил текст. 

Имею в виду, посмотреть, как по строкам выполняется скрипт, по каким ветвям условий выполняется в этом случае.

Зверев Александр,

 Отработка скрипта при сохранении 5-ой записи с полями "Ежедневно" и "Да"
-Показывает, что перед добавлением было 4 записи: 

 

 

Далее, при попытке сохранить 6-ю записи с нужными полями, показывает что 5шт уже есть, то-есть пред. запись сохранилась и записалась:

 

 

Окей, работает, пробую изменить другую запись с рандомными полями на нужные.

Результат показывает, кол-во записей до изменения и сохранения записи на нужные поля.

 

 

Пробую еще раз добавить запись с нужными полями:

 

Попробуйте выполнить скрипт в отладке!

Зверев Александр,

currentCount - кол-во существующих записей с нужными полями.

Тут показывает, что есть уже 5(при попытке создать 6-ю)

Тут исполнение функции происходит после изменения и сохранения другой записи с произвольными полями на нужные.

Ошибку не выкидывает, а просто сохраняет и уже currentCount = 6

 

Но когда уже есть 6, функция не позволяет дальше создавать с нужными полями или даже изменять произвольную запись на запись с "Ежедневно" / "Да". 

 

То есть Ваша функция не вызывается при изменении существующей записи, а только для новых? Проверьте, выполняется ли вообще перед сохранением функция, добавленная в asyncValidate и доходит ли до вызова validateSwimmingPrograms. 

 

Правильные примеры валидации есть в этой теме  и в DocumentPageV2 пакета Document в «коробке»:

asyncValidate: function(callback, scope) {
	this.callParent([function(response) {
		if (!this.validateResponse(response)) {
			return;
		}
		Terrasoft.chain(
			function(next) {
				this.validateAccountOrContactFilling(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function(next) {
				this.validateUniqueNumber(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function(next) {
				callback.call(scope, response);
				next();
			}, this);
	}, this]);
},

 

Зверев Александр,

Спасибо огромное за наводку, разобрался.

Переделал что-бы функция реагировала на изменения: 

 

Показать все комментарии

Добрый день, уважаемые коллеги!

Есть следующий кейс: 1. На странице Контрагента указывается наше ответственное подразделение, выбирается из справочника.

2. В записях справочника Подразделений есть признак (булево) можно выбирать это подразделение для указания в Контрагентах или нет - UsrProhibitSelectionAccount

3. Нужно запретить выбор записи Подразделения, если признак UsrProhibitSelectionAccount = true

4. Настраиваю правило валидации, как описано https://academy.terrasoft.ru/documents/technic-sdk/7-16/dobavlenie-vali…

5. При выборе значения из справочника правило отрабатывает. Но если вводить запрещенное подразделение вручную, то оно спокойно остается в поле и позволяет сохранить значение.

Подскажите, пожалуйста, что нужно сделать в данном случае? Благодарю за помощь

Добавленные методы в карточку Контрагента

methods: {
			// Метод-валидатор значения колонки [UsrDepartment] // semmrn
            DepartmentValidator: function() {
                // Переменная для хранения сообщения об ошибке валидации.
                var invalidMessage = "";
                // Проверка значения колонки [UsrDepartment]
                var AccountDepartments = this.get("UsrDepartment");
                if (AccountDepartments.UsrProhibitSelectionAccount) {
                    // Если значение колонки [UsrAccountDepartments.UsrProhibitSelectionAccount] 
                    // запрещено к выбору = да, то
                    // в переменную invalidMessage помещается значение локализуемой строки с сообщением
                    // об ошибке валидации.
                    invalidMessage = this.get("Resources.Strings.DepartmentMustBeAllowed");
                }
                // Объект, свойство которого содержит сообщение об ошибке валидации.
                // Если валидация прошла успешна, в объекте возвращается пустая строка.
                return {
                    // Сообщение об ошибке валидации.
                    invalidMessage: invalidMessage
                };
            },
            // Переопределение базового метода, инициализирующего пользовательские валидаторы.
            setValidationConfig: function() {
                // Вызывает инициализацию валидаторов родительской модели представления.
                this.callParent(arguments);
                // Для колонки [UsrDepartment] добавляется метод-валидатор DepartmentValidator().
                this.addColumnValidator("UsrDepartment", this.DepartmentValidator);
                }
		},

 

Нравится

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

Для того, что Вы хотите есть как раз валидация, которую Вы пробовали в первом сообщении. Она должна предотвращать и от ручного ввода. Не смотрели в отладке, функция-валидатор выполняется, что в поле AccountDepartments и как срабатывает условие?

Доброго дня, Марина. Почему Вы не хотите сделать настройку посредством бизнес-правила (фильтрацией)? 

Марина, ещё можно деактивировать при помощи стандартного механизма:

Если одно или несколько значений справочника устарели и больше не используются, то такие значения можно деактивировать (Рис. 2). Деактивированное значение не будет отображаться при выборе значений в справочных полях. При этом пользователи продолжат видеть это значение в тех записях, где оно было указано ранее, и смогут использовать его для фильтрации. По умолчанию возможность деактивировать значения справочника выключена. Разрешить деактивацию записей для нужного справочника можно в разделе [Конфигурация]. Подробнее о настройке читайте в статье “Деактивация записей объектов”.

Рис. 2 — Деактивированное значение справочника [Типы статей базы знаний]

section_lookups_deactivated_record_example.png 

Но так будет запрещён выбор не в конкретной карточке, а везде. 

Уважаемые коллеги, спасибо за Ваши предложения.

Стандартные фильтры и деактивация не подходят, так как в справочнике настроена иерархия, которая не совмещается с данными инструментами.

Нет ли метода, который будет проверять значение при вводе вручную? а также при открытии страницы (так как неправильные записи у нас пока появляются в результате их создания в мобильном приложении)? Благодарю за помощь

Для того, что Вы хотите есть как раз валидация, которую Вы пробовали в первом сообщении. Она должна предотвращать и от ручного ввода. Не смотрели в отладке, функция-валидатор выполняется, что в поле AccountDepartments и как срабатывает условие?

Зверев Александр,

 

благодарю), ситуация, действительно, прояснилась через отладчик

Показать все комментарии

Коллеги, есть способ добавить валидацию к полю детали страницы?

Нравится

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

Похожий вопрос и разные подходы к его решению обсуждались тут. Также валидация детали описана в статье SDK в п. 2.

Показать все комментарии

Добрый день.

Нужна помощь в реализации одного вопроса.

 

В Обращениях есть справочная колонка, допустим "Квартира". При создании Обращения можно выбрать в колонке "Квартира" значение "Запрещено".

Надо сделать так, что-бы при выборе значения "запрещено" - появлялась валидация или всплывающее окно. Но что-бы окно только предупреждало, что "Квартира - запрещено" и была возможность сохранять даже с данным значением.

 

Подскажите, каким образом можно реализовать этот момент.

Нравится

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

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

Похожее обсуждали тут и тут. Также см. статью.

Показать все комментарии

Добрый день,

Есть несколько преднастроенных страниц (использую в БП). Необходимо настроить валидацию определенных полей (напр. только цифры).
Пробовала настроить по аналогии с валидацией на странице раздела, но на преднастроенной странице валидация не срабатывает.

Явно, я что-то упускаю срецифическое для преднастроенных страниц? Просьб направить в правильном направлении.

Пример метода, которй я использую:

            setValidationConfig: function() {
               this.addColumnValidator("CrpINN", this.innValidator);
            },
                innValidator: function(value) {
                var invalidMessage = "";
                var isValid = true;
                var number = value || this.get("CrpINN");
                isValid = (Ext.isEmpty(number) ||
                    new RegExp("^[0-9]{8}$").test(number));
                if (!isValid) {
                    invalidMessage = this.get("Resources.Strings.InvalidINNCodeFormat");
                }
                return {
                    invalidMessage: invalidMessage
                };
            },
      

Заранее спасибо.

 

 

Нравится

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

судя по всему проблема в том, что преднастроенная страница и обычная страница раздела унаследованы от разных родителей. Следовательно в зависимости преднастроенной нужно добавить тот модуль, в котором реализован функционал валидации. Беглым поиском нашел BaseSchemaViewModel, однако не уверен на 100%.

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

Вадим Косарев,

 Спасибо! Я обязательно разберусь с зависимостями.

 

Но, я совсем новичек с ограниченным временем на поиск решения. Буду благодарна, если подскажете, как можно настроить проверку поля без стандартной валидации. Ничего подобного на академии или в комьюнити не нашла. Возможно неправильно задаю поиск?  

Ксения, если там должны быть только цифры, может вместо валидации получится с добавлением маски телефонного номера? Пример описан тут.

Все оказалось гораздо проще  - для преднастроенной страницы необходимо указать поле+сослаться на основную страницу. Все заработало.

 

setValidationConfig: function() {
             this.addColumnValidator("CrpPortalProductRequest1.CrpINN", this.innValidator);
            },
                innValidator: function(value) {
                
                var invalidMessage = "";
                var isValid = true;
                var number = value || this.get("CrpPortalProductRequest1.CrpINN");
            
                isValid = (Ext.isEmpty(number) ||
                    new RegExp("^[0-9]{8}$").test(number));
                if (!isValid) {
                    invalidMessage = this.get("Resources.Strings.InvalidINNCodeFormat");
                }
                return {
                    invalidMessage: invalidMessage
                };
            },

Показать все комментарии

Добрый день. Применил валидацию даты согласно статье https://academy.terrasoft.ru/documents/technic-sdk/7-15/dobavlenie-validacii-k-polyu-stranicy
Всё работает хорошо. Но при удалении значения  поля почему, то распознаёт что не проходит валидацию. 
У меня поле желаемая дата не должна быть меньше текущей даты и времени или должно быть пусто. Пустым полем он не даёт сохранить. Скрин вложил. 
https://i.imgur.com/H9hksBj.png

 

Вот код:

// Метод-валидатор значения колонок [UsrCustomDate] и [CreatedOn].
            dueDateValidator: function() {
                // Переменная для хранения сообщения об ошибке валидации.
                var invalidMessage = "";
                // Проверка значений колонок [UsrCustomDate] и [CreatedOn].
                if (this.get("UsrCustomDate") < this.get("UsrDateReal"))  {
                    // Если значение колонки [UsrCustomDate] меньше значения колонки [CreatedOn], 
                    // в переменную invalidMessage помещается значение локализуемой строки с сообщением
                    // об ошибке валидации.
                    invalidMessage = this.get("Resources.Strings.CreatedOnLessDueDate");
                }
        
                // Объект, свойство которого содержит сообщение об ошибке валидации.
                // Если валидация прошла успешна, в объекте возвращается пустая строка.
                return {
                    // Сообщение об ошибке валидации.
                    invalidMessage: invalidMessage
                };
            }

Нравится

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

Если в базе в поле Null, не факт, что в переменной JS тоже так. добавьте вывод в лог, посмотрите что там, а затем можно будет вписать в условие if проверку на такое значение.

Не смотрели, что попадает в переменную при очистке? Может, там как раз минимальная дата, вроде 01.01.01? Или оба сравниваемые поля пустые, их значения одинаковы и строгое сравнение при помощи «<» даёт отрицательный ответ? Попробуйте отладиться или просто выводить в консоль значение полей и результаты проверки.

Зверев Александр,

Насколько я понял NULL. А NULL это меньше текущей даты. Можно ли 

        if (this.get("UsrCustomDate") < this.get("UsrDateReal")) как то изменить.? Чтобы принимал тоже NULL.

 

 

Если в базе в поле Null, не факт, что в переменной JS тоже так. добавьте вывод в лог, посмотрите что там, а затем можно будет вписать в условие if проверку на такое значение.

Я по трассировке проверил почему то window.console.log(); ничего не возвращает. 

  if (this.get("UsrCustomDate") < this.get("UsrDateReal"))  {
                      if (this.get("UsrCustomDate") !== null)  {
                    // Если значение колонки [UsrCustomDate] меньше значения колонки [CreatedOn], 
                    // в переменную invalidMessage помещается значение локализуемой строки с сообщением
                    // об ошибке валидации.
                    invalidMessage = this.get("Resources.Strings.CreatedOnLessDueDate");
                }
                }

 

А есть ли текущее значение, а то я через бизнес-процессы обновляю всегда поле UsrDateReal???

В JS текущую дату и время можно узнать при помощи присвоения или сравнения с new Date().

Я проще нашёл решение. Просто к сравнительному полю привязал системную переменную текущая дата https://i.imgur.com/Xf3bcEA.png

С new Date() нужно было попотеть по моему. 

Мне кажется, от лишнего поля в таблице расходов ресурсов всё же больше, чем от пары строк на JS, даже если нужно привести к нужному формату кодом.

Показать все комментарии

Предлагаю создать пользовательскую настройку проверок перед сохранением карточки.

Где в условиях фильтра можно было бы описать условие некорректности, задать сообщение и указать, блокировать ли сохранение при этом или разрешать.

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

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

Добрый день, Владимир.

Ваша идея может быть составляющей более общей, которая подавалась ранее:

Бизнес правила. Валидация введенных значений по условию. Нужна возможность пользовательской настройки правил, которые будут определять условия заполнения полей. При настройке правил есть необходимость использовать: значения полей объекта, значение полей связанных объектов (прямые связи или по наличию записей на детали, сис. параметры, сис. настройки, вхождение пользователя в определенные группы и роли, или комбинации перечисленных параметров).

Показать все комментарии

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 тогда застреваю на замыкании.

Спасибо всем кто окажет помощь в решении проблемы.

Нравится

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

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 запроса можно так же получить раньше и сохранить в атрибут, а потом уже при валидации оперировать существующими значениями. Ну или сделать так, как посоветовал Варфоломеев Данила.

Показать все комментарии