Pull to refresh

Javascript. Простой Observer.

Reading time2 min
Views1.4K
Задача — связать 2 абсолютно любые объекта. Менять исходный код объектов нельзя.

Описанное ниже расчитано на самостоятельность читателя и желание разобраться в реализации.



Пример (утрированный).

Есть 2 объекта в доме:
<div id="a1" onclick="alert(123)"></div>
<div id="a2"></div>



И 1 яваскриптовый:
Core = function() {
	this.some = function(a,b,c,d,e,f,g) {
		var a1 = $('a1').innerHTML
		var a2 = a+''+b+''+c+''+d+''+e+''+f+''+g
		$('a1').innerHTML = a1 + a2
	}
	this.another = function() {
		var a = $('a1').innerHTML
		var a2 = 'some_text_more'
		$('a1').innerHTML = a + a2
	}
	this.another2 = function() {
		var a = $('a2').innerHTML
		var a2 = 'yahoo'
		$('a2').innerHTML = a + a2
	}
}
var Core = new Core()



Требуется: отреагировать на a1.onclick вызовом Core.another2

Реализация:
var n = Observer.Attach($('a1'), 'onclick', Core, 'another')



Убираем Observer:
Observer.Dettach($('a1'), n)



Observer.
Реализация построена на клонировании метода отслеживаемого объекта.
Observer.Attach клонирует метод, создавая новый с уникальным именем.
Отслеживаемому методу присваивается новое действие, содержащее вызов клона и вызов необходимой функции (obj2.call_back)
Очередность вызова контролируем параметром before метода Observer.Attach.
Observer = function() {}
			
Observer.prototype = {
	
	List: {},
	
	Attach: function(obj, method, obj2, call_back, before) {
		var new_method = this.CloneOldMethod(obj, method)	
		eval('obj.'+method+' = '+this.NewDefaultMethod('obj2', call_back, new_method, before))
		return new_method 
	},
	
	Dettach: function(obj, observed_method) {
		eval('var m = this.List.'+observed_method)
		eval('obj.'+m.method+' = m.realization')
		eval('delete(obj.'+observed_method+')')
		eval('delete(this.List.'+observed_method+')')
	},
	
	NewDefaultMethod: function(obj_name, call_back, new_method, before) {
		var m_old = 'this.'+new_method+'(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6])'
		var m_new = obj_name+'.'+call_back+'()'
		var cmd = ''
		cmd += 'function() {'
		before === true ? cmd += m_new +';'+ m_old : cmd += m_old +';'+ m_new
		cmd += '}'
		return cmd
	},
	
	CloneOldMethod: function(obj, method) {
		var new_method = 'a'+this.giveUnique()
		eval('obj.'+new_method+' = obj.'+method)
		eval('this.List.'+new_method+' = {object: obj, \'method\': method, realization:obj.'+method+'}')
		return new_method
	},
	
	giveUnique: function () {
		return (new Date()).getTime()
	}
}

Observer = new Observer()


Tags:
Hubs:
Total votes 9: ↑7 and ↓2+5
Comments25

Articles