Before start to explain, I Know some of you might have greater
experience about this word Proxy. what does this really means?

Let me explain it through simple example, In our school days when class teacher used to take class attendance and if we found some of our friend missing then we still used to hear from back "yes madam" even though the person called is missing in the class. That is nothing but a proxy attendance, It means answering on behalf of someone and you all know if the proxy person caught up then...........:)

Oh,sorry so i forgot we are talking about a proxy. So what is proxy in computer programming world?

The proxy pattern is a software design pattern, In its most general form, is a class functioning as an interface to something else. The proxy could relate or interface to anything: a network connection, a file, a large object in memory or some other resource that is expensive or impossible to duplicate.

Recently, We approach to proxy pattern. How? In our project we are mostly using knockout.js framework using typescript for client side part. So we were facing issue in calling a function present in the knockout-component from outside the scope.

I am assuming that you all know how the knockout component works, if not you should first go through this links: Component Binding in knockout with example

Just to have overview a knockout component consist of a view and ComponentModal.

  • View is nothing but the UI.
  • ComponentModal is to which the view is bound too

Now we can say that the view is tightly coupled with that ComponentModal. The view will be bound to that ComponentModal object only.We all know a component gets instantiated/created run time. so we don't have control over the object of the Component when actually it got instantiated/created. so now from outside if we want to call a function and set some value on the Component we can't do that as we don't have object reference of the Component present outside to invoke the function on that. Even if we somehow manage to call a function present in component form outside but still it may be fail in a position when the component is not yet created and we tried to setValue on that component in that case it might break all your webpage.So how to overcome over this problem we approached to Proxy pattern.

Now i will explain how we did that.

So, First of all we created two class one is abstract and other is the generic proxy class like below.

 export abstract class BaseClass {
        abstract setValue(o: any): void;
        constructor(params?: any) {
            super();
            if (params) {
                if (params.proxy) {
                    setTimeout(() => params.proxy.component(this), 1);
                }
             }
         }
   }



 export class ComponentProxy<T> extends BaseClass {
        private _component: T;
        private data: any;
       public component(cmp?: T): T {
            if (arguments.length != 0 && cmp) {
                this._component = cmp;
                if (this.data) {
                        this._component.setValue(this.data);
                    }
                }, 100);                
            }
            return this._component;
        }
        public setValue(value: any) {
            this.data = value;
            if (this._component) {
                this._component.setValue(value);
            } 
        }
}

This is the student entry view

<template id="tplStudentEntryView">
    <div class="row">
        <div class="col-md-12 form-group">
            <input type="text" class="form-control" placeholder="Name" data-bind="value:studentName">
        </div>
    </div>
</template>

This is our componentModal : A class to which student entry view will be bound.

export class StudentEntryComponentModal extends BaseClass {
    	studentName: string;
    
     	constructor(params: any) {
                super(params);
    	}
    
     	public setValue(value: any) {
             this.studentName=value;
            }
    }
ko.components.register('student-entry', {
    viewModel: StudentEntryComponentModal ,
    template: { element: 'tplStudentEntryView'}
});

This is a outside class which has a implementation.

 export class SchoolComponent extends BaseClass {
 	studentEntryProxyComponent : ComponentProxy<StudentEntryComponentModal>;

 	constructor(params: any) 
	{
       	 	super(params);
    	        this.studentEntryProxyComponent = new ComponentProxy<StudentEntryComponentModal>();
   		        this.studentEntryProxyComponent.setValue('xyz');
	}
}

This is how knockoutcomponent called and we are passing a proxy object to grab the real object which will be creating run-time when the component will be rendered

 <student-entry params="proxy: studentEntryProxyComponent"> </student-entry>

Now, i will explain how this will work.

  • As i said every component has view and modal.We have a component by the name student-entry which is bound to the StudentEntryComponentModal.

  • Whenever the component will be called it will create the object of that component run-time that is true. Now we have passed the studentEntryProxyComponent object as parameter so that we can grab that component object address when the component will be really instantiated. once we get the object we can then call any function on that. For now the studentEntryProxyComponent is nothing but a proxy object.

  • So how we will grab that object, now whenever the component will get created it will call the constructor which has the super(params). what does this will do is that it will call the base class constructor and will check whether the property has proxy type object or not if it has then it will invoke a function by the name component which is present in that proxy object and will set the current object address to the property by the name _component.

  • Now we have a real object available in the _component property.

  • now whenever we will call the setValue function on the proxy object then it will check the _Component property if it is present then it will invoke a function on that object. This is how we can call a function present in the component using proxy pattern.

  • Now in using proxy pattern we never care about whether the component has been created or not so that we can call a function over that. If you will go over through that componentProxy class it will take care of so.

References:
1: https://en.wikipedia.org/wiki/Proxy_pattern