📜 ⬆️ ⬇️

Javascript. Simple Observer.

The task is to link 2 absolutely any objects. You cannot change the source code of objects.

Described below is designed for the reader's independence and the desire to understand the implementation.


')
Example (exaggerated).

There are 2 objects in the house:
 <div id = "a1" onclick = "alert (123)"> </ div>
 <div id = "a2"> </ div>



And 1 javascript:
 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 ()



Required: Respond to a1.onclick by calling Core.another2

Implementation:
 var n = Observer.Attach ($ ('a1'), 'onclick', Core, 'another')



Remove Observer:
 Observer.Dettach ($ ('a1'), n)



Observer.
The implementation is built on the cloning method of the monitored object.
Observer.Attach clones the method, creating a new one with a unique name.
A new action is assigned to the monitored method, containing a clone call and a call to the necessary function (obj2.call_back)
The order of the call is controlled by the before parameter of the Observer.Attach method.
 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 ()


Source: https://habr.com/ru/post/30312/


All Articles