macik_spb
@macik_spb
Ф-ф-фрилансер :))

Knockout.js: как правильно расширить функционал наблюдаемой переменной (ko.observable)?

Использую KnockoutJS.
Хочу сделать возможность редактирования наблюдаемой переменной через копию значения, с возможностью применить изменения или сбросить.
«Расширение» делаю через экстендеры (описание).

Задачи стоят следующие:
1. создать базовый утилитарный класс общий для разнообразных расширений
2. удобно задавать функционал в каждом отдельном расширении
3. минимально «засорять» расширяемую переменную доп.методами и свойствами
4. обходить (корректно обрабатывать) случаи вызова расширенных методов из интерфейса, если переменная по каким-то причинам не была «расширена».

Меня интересуют ваши советы как по отдельной оптимизации, так и в целом о правильности идеи реализации. Особенно меня беспокоит пункт 4.

Ниже примитивный код для иллюстрации. Или он же на CodePen.
// базовый класс для различных расширений
var basicAction = function(p,o,t){
	var self = this;
	// пока здесь пусто. это «на вырост»
	self.allowed = o;
};
// расширяем функционал функциями редактирования
ko.extenders.editAction = function(t,o){
	var self = this;
	var Action = new basicAction('some',o,t);

	// основные методы за счет которых переменная получит новые возможности
	Action['fn'] = {
		editStart: function(item){ // начинаем редактирование переменной
			console.log('editStart:'+item);
		},
		editSave: function(item){ // созраняем измененное значение
			console.log('editSave'+item);
		},
		editCansel: function(item){ // откатываемся на начальное значение
			console.log('editCancel'+item);
		}
	};

	// создаем ф-и заглушки на случай «непредвиденного» вызова
	ko.utils.objectForEach(Action['fn'], function(actionName,action){
		Action[actionName] = function(){ // dump func
			console.log('dump func');
			return t;
		};
	});

	// если функционал редактирования включен
	if (Action.allowed) {
		// расширяем объект основными методами
		ko.utils.extend(Action, Action['fn']);
	}

	Action.actionSome = Action; // делаем ссылку на себя
	ko.utils.extend(t, Action); // добавляем функционал к observable переменной
	return t;
};

a = ko.observable(15).extend({editAction:true}); // подключаем возможность «редактирования с отменой»
a.editStart(); // просто проверяем вызов нужной ф-и — все ок
a.extend({editAction:false}); // отключаем функционал редактирования
a.editStart(); // проверяем, что ничего не происходит (срабатывает ф-я заглушка)
  • Вопрос задан
  • 3203 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы