Lets take a look at a quick example of how it works. First lets create an Account object (note that there would typically be setter methods for these functions as well but they are left out for brevity's sake):
<cfcomponent hint="Test very simple cfc for searalization to javascript"> <cfscript> variables.accountNumber = 0; variables.accountName = ""; variables.productArray = []; variables.insuredProducts = {}; variables.PBJ = ""; </cfscript> <cffunction name="init" returntype="Account" access="public" output="false" hint="" > <cfscript>
//create the PBJ object and pass in a reference to this
variables.PBJ = createObject("PBJ").init(this); return this; </cfscript> </cffunction> <cffunction name="getAccountNumber" returntype="numeric" access="public" output="false" hint="" > <cfscript> return variables.accountNumber; </cfscript> </cffunction> <cffunction name="getAccountName" returntype="String" access="public" output="false" hint="" > <cfscript> return variables.accountName; </cfscript> </cffunction> <cffunction name="toJS" returntype="String" access="public" output="false" hint="Proxy to the PBJ toJS method" > <cfscript> return variables.PBJ.toJS(); </cfscript> </cffunction> <cffunction name="getProductArray" returntype="Array" access="public" output="false" hint="" > <cfscript> return variables.productArray; </cfscript> </cffunction> <cffunction name="getInsuredProducts" returntype="Struct" access="public" output="false" hint="" > <cfscript> return variables.insuredProducts; </cfscript> </cffunction> </cfcomponent>
If you look closely at the Init method you'll see that a PBJ object is created and initalized and the "this" reference is passed to it. This tells PB&J to inspect the current object for its "getter" methods defined by the naming convention getXXX. PB&J will look for all getter methods that return strings, numbers, arrays, and structures. This object also defines a proxy function called "toJS"that calls the PBJ.toJS() method. When this method is invoked it will run all of your object's getter methods, save the return data, and output JavaScript that is a mirror of your object with its getter methods and its data. Lets take a look at an example of this in action. First lets create an instance of the account object and set some of its data:
Now in our .cfm page we output the value of #account.toJS()# in the header to produce our JavaScript representation of our object:account = createObject("Account").init(); account.setAccountNumber(12345); account.setAccountName("Ryan ""Pretty Boy"" Anklam");
< script type = "text/javascript" charset = "utf-8" > var Account = (function() { var accountName = "Ryan \"Pretty Boy\" Anklam"; var productArray = []; var insuredProducts = {}; var accountNumber = 12345; return { getAccountName: function() { return accountName; }, getProductArray: function() { return productArray; }, getInsuredProducts: function() { return insuredProducts; }, getAccountNumber: function() { return accountNumber; } }; })(); < /script>
Looking at the JavaScript you'll see that CF PB&J created a few private variables and returned public methods to return that data. It's meant to be a "read-only" representation of the internal state of your object. PB&J will also work on calculated fields as it just invokes your getter methods and saves its output.
Now in any of your scripts you can access the object's data by calling the JavaScript object's getter methods:
< script type = "text/javascript" charset = "utf-8" > Account.getAccountName(); Account.getAccountNumber(); < /script>