Вопрос

Проблема с замещением модуля - LookupPageViewModelGenerator

Здравствуйте, Коллеги! 
На страничке редактирования детали есть справочное поле Контрагент, мне нужно чтобы при нажатии на кнопку "Добавить" - открывалась страничка создания нового контрагента, у которого будет проставлен в поле "Тип" - Конкурент, и чтобы это поле было нередактируемым.
Логика этой кнопки прописана в модуле - LookupPageViewModelGenerator. Всё вроде бы понятно, заместить этот модуль и передавать сообщение в карточку контрагента. Но проблема в том, что любая попытка замещения этого модуля влечет за собой последствия, показанные во вложенном скрине, проблема наблюдается во всех справочниках. Коллега подсказал, что такого рода модули навряд ли получится нормально заместить, но если это так, то как тогда решить мою задачу? Надеюсь на вашу помощь :)

У меня такой же вопрос

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

Вообщем если Вам требуется кастомизировать какой либо lookup (я уже сталкивался с такой задачей не раз) у меня это вышло вот таким вот способом, Вам надо не замещать. (Это вообще сомнительное изначально решение, т.к. логика схемы LookupPageViewModelGenerator в приложении используется повсеместно, и менять ее для всех из-за одного кейса не корректно)
и так...
Необходимо создать совой новый модуль, и объявить в нем свой элемент "окно справочника", модуль сам по себе не должен никакую схему наследовать или замещать (т.е. поле родительский объект должно быть пустым)
 

define("CustomLookupPage", ["LookupPage", "LookupPageViewGenerator", "LookupPageViewModelGenerator",
"ProcessModuleUtilities", "LookupUtilities", "css!LookupPageCSS"],
	function(LookupPage, LookupPageViewGenerator, LookupPageViewModelGenerator, ProcessModuleUtilities) {
		return Ext.define("Terrasoft.configuration.CustomLookupPage", {
			alternateClassName: "Terrasoft.KmGMSLookupPage",
			extend: "Terrasoft.LookupPage",
			gridWrapClasses: ["custom-lookup-control"]
		})
	}
)

здесь же дополнительными свойствами конфигурационного объекта для вызова define вы можете переопределять методы, полезными в данном случае будут замещения методов 

generateViewModel

и

renderLookupView

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

н/п переименуем кнопки, кое что скроем, подменим обработчик.

//Переопределяем метод в котором мы можем управлять сформированной конфигурацией до рендеринга.
renderLookupView: function(schema, profile) {
	var config = this.getLookupConfig(schema, profile);
	var topPanelConfig = LookupPageViewGenerator.generateFixed(config);
	//----------------------- инъекция логики (начало) ----------------------
	var buttonsConfig;
	//Получаем ссылку на аттрибут-массив конфигурационных объектов-кнопок
	//Используем Underscore.some с возможностью прерывания переборы по возврату от предиката "true"
	_.some(topPanelConfig.items, function(target) {
		//выделяем объект группы кнопок (Wrapper) по id контейнера
		if (target.id === "selectionControlsContainerLookupPage") {
			//в нем ищем подчиненные объекты являющиеся массивом
			_.some(target, function(target) {
					//согласно структуры конфигурационного объекта панели
					//"чистым" массивом является только объект с конфигами кнопок
				if (Array.isArray(target)) {
					//сохраняем ссылку на него в переменной для дальнейшего использования
					buttonsConfig = target;
					//Прерываем перебор
					return true;
				}
			});
			//Прерываем перебор
			return true;
		}
	});
	//Поиск конфигурационного объекта кнопки "Выбрать" в искомом массиве по caption
	_.some(buttonsConfig, function(target) {
		if (target.caption === "Выбрать") {
			//В найденном объекте меняем значение аттрибута caption на "Создать тендеры".
			target.caption = "Создать тендеры";
			return true;
		}
	});
	//Поиск конфигурационного объекта кнопки "Добавить" в искомом массиве по caption
	_.some(buttonsConfig, function(target) {
		if (target.caption === "Добавить") {
			//В найденном объекте меняем значение аттрибута caption на "Создать тендеры".
			target.caption = "Создать запрос";
			//Удаляем тег стандартного действия "Создать запись" (add)
			//исключая навешивания стандартного обработчика в viewmodel генераторе 
			delete target.tag;
			//Устанавливаем совой обработчик
			target.click = {
				bindTo: "AddRequestButton"
			};
			return true;
		}
	});
	//Поиск конфигурационного объекта кнопки "Добавить" в искомом массиве по caption
	_.some(buttonsConfig, function(target) {
		if (target.caption === "Действия") {
			//В найденном объекте меняем значение аттрибута visible на "false"
			//тем самым скрывая кнопку-меню
			target.visible = false;
			return true;
		}
	});
	//----------------------- инъекция логики (конец) ----------------------
	this.renderLookupControls(config, topPanelConfig);
}

view будет выполнять в другом контексте и чтобы расширить его своим методом:

//Переопределяем метод в котором мы можем расширить viewModelConfig собственным методом.
generateViewModel: function() {
	var viewModelConfig = LookupPageViewModelGenerator.generate(this.lookupInfo);
	if (!this.lookupInfo.columnValue && this.lookupInfo.searchValue) {
		viewModelConfig.values.searchData = this.lookupInfo.searchValue;
		viewModelConfig.values.previousSearchData = this.lookupInfo.searchValue;
	}
	//----------------------- инъекция логики (начало) ----------------------
	//Добавляем свой пользовательский метод
	viewModelConfig.methods.AddRequestButton = function() {
		//Проброшенный через конфиг страницы Id связанного Проекта
		var associatedProjectId = this.values.LookupInfo.associatedProjectId;
		//Вызываем БП
		var args = {
			sysProcessName: "CreateNewRequestFromProject",
			parameters: {
				ProjectId: associatedProjectId
			}
		};
		ProcessModuleUtilities.executeProcess(args);
		this.close();
	};
	//----------------------- инъекция логики (конец) ----------------------
	var viewModel = this.Ext.create("Terrasoft.BaseViewModel", viewModelConfig);
	viewModel.Ext = this.Ext;
	viewModel.sandbox = this.sandbox;
	viewModel.Terrasoft = this.Terrasoft;
	if (this.lookupInfo.updateViewModel) {
		this.lookupInfo.updateViewModel.call(viewModel);
	}
	viewModel.initCaptionLookup();
	viewModel.initHasActions();
	viewModel.initLoadedColumns();
	if (!this.Ext.isEmpty(this.lookupInfo.filterObjectPath)) {
		viewModel.updateFilterByFilterObjectPath(this.lookupInfo.filters, this.lookupInfo.filterObjectPath);
	}
	if (this.lookupInfo.hideActions) {
		viewModel.set("hasActions", false);
	}
	return viewModel;
}

 

Далее чтобы вызвать свое кастомизированное окно справочника используйте метод openLookup

//конфигурационный объект для кастомного окна справочника
var config = {
	entitySchemaName: "Lead",
	columns: ["Id"],
	associatedProjectId: this.get("Id"),
	multiSelect: true,
	filters: filterGroup,
	actionsButtonVisible: true,
    //указываем нашу кастомизированную схему
	lookupPageName: "CustomLookupPage"
};
this.openLookup(
	config,
	function(selected) {
       //callback обрабатывающий результаты выбора
	},
	this
);

 

PS: не пробовал но должно прокатить и через lookpListConfig для какого ни будь справочного поля в теории там lookpListConfig и превращается в config для openLookup :)

Суть ошибки на скриншоте в том, что не подтянулась локализируемая строка CaptionLookupPage. Необходимо добавить в замещающий модуль её вручную.

Спасибо, Коллеги! Как руки доберутся до этой задачи, дам знать получилось ли:)

Мотков Илья,

Добрый день, проверил, в модуле эта лок. строка присутствует. Не хотелось бы из-за этой задачи создавать свое кастомиз. окно справочника, неужели нет другого выхода:(

Войдите или зарегистрируйтесь, чтобы комментировать