Подстановка значения по умолчанию в поле карточки

Добрый день.

Я добавил в конфигурацию два раздела "Складские документы" и "Размещения". В объекте и карточке раздела "Складские документы" имеется поле "Склад", которое ссылается на объект раздела "Размещения". В объекте раздела "Размещения" есть логическое поле "Значение по умолчанию", которое должно принимать значение true только для одной записи в разделе.

Задача заключается в том, чтобы разобраться как в схеме модели представления карточки запрограммировать логику, по которой в страничку редактирования будет подставляться значение по умолчанию из раздела "Размещения".

Суппорт почему-то предложил мне инициализировать значением этого поле во встроенном процессе объекта "Складские документы" ( :) вероятно тот кто мне отвечал забыл, что у объекта нет события уровня инициализации объекта ).

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

Вот решение:

onEntityInitialized: function() {
        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) и для чего он нужен вообще :)?

Нравится

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

Геннадий, здравствуйте!

Отвечу по порядку:
1. Да, выбран корректно.
2. Правильно сделали. Но хотелось бы отметить следующее, что Вы не совсем правильно используете работу с коллекцией. Т.е. написано правильно, но логично работу с коллекцией выполнять примерно так:

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);

3. Правильно. СallParent используется для вызова метода родительских объектов. И если Вы хотите, чтобы маска загрузки проходила быстрее, т.е. скрывалась, то нужно callParent ставить в самом начале.

Добрый день, Дмитрий!

Спасибо за ваши замечания по коду.
Сегодня я получил ответ от ТП и в результате "компиляции" вашего примера и примера от ТП получил результирующий код:

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);
}

В принципе мне все понятно, кроме назначения строк:
1. var self = this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
2. self.apply(scope || this, [callback, scope || this]);

Геннадий, при использовании

var self = this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
self.apply(scope || this, [callback, scope || this]);

вызивать this.callParent(arguments); не нужно. Это уже происходит во второй строке.
Данная конструкция реализует своего рода «замыкание». Это необходимо для того, чтоб поле заполнялось сразу, а не спустя некоторое время. Данное поведение связано с ассинхронностью вызовов встроенных функций.
Первая строка – ссылка на метод родителя.
Вторая строка – замыкание внутри функции и вызов замещенного метода родителя.

Спасибо, Дмитрий!

Хочу отметить, что в коде ошибка копипаста :)

var storeId = store[0].get("Id");

*

var storeId = store.get("Id");

Дмитрий, я убрал

this.callParent(arguments);

а в консоль стала выводится строка: Cannot read property 'apply' of undefined
Вот код:

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);
}

если строку //this.callParent(arguments); раскоментировать, то карточка грузится мгновенно и никаких ошибок нет.

Попробуйте, пожалуйста, сделать наоборот, оставить callParent, а убрать

var self =this.setEntityDefaultValues.$owner.superclass.setEntityDefaultValues;
self.apply(scope || this, [callback, scope || this]);

Если сделать так как вы сказали, то ошибки нет и страничка загружается быстро.

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