Jump to content
Sign in to follow this  
lynkfs

proxy

Recommended Posts

I recently came across the javascript proxy object

A proxy object basically monitors a chosen object, and has getter and setter functions which are invoked when the value of any of its properties changes (set) or are being accessed (get).

In that respect there are some similarities with the mutationobserver object.

In the below code snippet a regular EditBox has its text saved in a proxied object, which triggers the setter function
and a Button which reads that value and thus triggers the getter function

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components

  var Edit1 : TW3EditBox := TW3EditBox.Create(self);
  Edit1.SetBounds(32,40,300,32);

  var Button1 : TW3Button := TW3Button.Create(self);
  Button1.SetBounds(340,40,200,32);
  Button1.Caption := 'read';

  var Memo1 : TW3Memo := TW3Memo.Create(self);
  Memo1.SetBounds(32,90,300,100);

//set proxies
  var MyProxy  : variant := new JObject;
  var ProxyObj : variant := new JObject;
  ProxyObj.EditBox1 := 'initialvalue';    //will be overwritten

  Edit1.OnInput   := lambda MyProxy.EditBox1 := Edit1.Text; end;      //triggers 'handler.set'
  Button1.OnClick := lambda Button1.Caption := MyProxy.EditBox1; end; //triggers 'handler.get'

  var handler : variant := new JObject;
  handler.get := function(obj, prop: variant): variant
  begin
    Memo1.Add('someone read ' + prop + ' as ' + obj[prop] + #10);
    result := obj[prop];
  end;
  handler.set := function(obj, prop, value: variant):variant
  begin
    Memo1.Add('someone set ' + prop + ' to ' + value + #10);
    obj[prop] := value;
    result := true;
  end;

  asm
    @MyProxy = new Proxy(@ProxyObj,@handler);
  end;

end;

 

This mechanism could f.i. be used to bind form components with a data source, updating them automatically when data changes or is being accessed

Demo

 

Share this post


Link to post
Share on other sites

Quite interesting, I've done something similar and never knew this was possible. Do you know how does it handle setting subobjects, for example, you're proxying object which has 5 levels of subobjects and some property in level3Object is changed?

Share this post


Link to post
Share on other sites

I didn't know of this object either until recently. It has been around for a long time and is supported in all browsers.

afaik it handles subobjects as well

I'll check it out

Share this post


Link to post
Share on other sites

The proxy object does handle deeper levels as well

code below refers to earlier post :

//set proxies
  var MyProxy  : variant := new JObject;
  var ProxyObj : variant := new JObject;
  var leveltest: variant := new JObject;
  ProxyObj.leveltest := leveltest;
  ProxyObj.leveltest.level := 'initiallevel';

  Button2.OnClick := lambda Button2.Caption:= MyProxy.leveltest.level; end;

  var handler : variant := new JObject;
  handler.get := function(obj, prop: variant): variant
  begin
    writeln(json.stringify(obj));
    Memo1.Add('someone read ' + prop + ' as ' + obj[prop].level + #10);
    result := obj[prop];
  end;

 

Share this post


Link to post
Share on other sites

Thanks, it seems to intercept any level get but only first (tracked) level set.

leveltest.level2 := new JObject;

  ProxyObj.leveltest := leveltest;
  ProxyObj.leveltest.level2.level3 := 'level3Value';

  Button3.OnClick :=
    lambda
      Memo1.Add(MyProxy.leveltest.level2, True);

      MyProxy.leveltest.level2.level3 := 'changedLev3Value';

      Memo1.Add(MyProxy.leveltest.level2.level3, True);

      MyProxy.leveltest := 'changedLev1Value';
      leveltest := 'changedLev1Value2';

      Memo1.Add(MyProxy.leveltest, True);
    end;

 

Share this post


Link to post
Share on other sites

Edited

Had a look at vue, but never used it.

After some more testing of the proxy object, my conclusion is that you are right.

Proxy objects track 'reads' across all properties of the tracking object, any level deep. 'Writes' though are only tracked on the same level as where they are specified.

Sort of logical as a set-handler only gets as input an object, property and value, and as properties can have the same name across levels, it wouldn't know what to track.

It is feasible though to set subsequent proxies on deeper levels, and code specific set-handlers for it ...

   


 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...