javascriptjquery-ui-widget-factory

Passing function object references as serialized json


I have written some widgets using the jquery widget factory. Normally, I pass options and callback references using the widget constructor in a JavaScript code block.

Now I want to use the widgets in auto generated html pages and pass options to them without using JavaScript blocks. I am specifying the options in embedded json which a common JavaScript code block parses and passes it on to the widget.

<div id="search_widget">
    <script type="application/json">
    {
        "search": {
            "search_string": "text to be searched",
            "callback": "a function object in an outer scope"
        }
    }
    </script>
</div>

How do I pass the function objects preserving their scope to the widgets in json format ? The widget will then call the function specified when a condition is met.

Thanks for your help.


Solution

  • You can pass the function body as text, but your receiving context will have to know it's a function and "reconstitute" it with the Function constructor (or something). You can't preserve the "scope", though that doesn't really mean much in a block of JSON.

    You could also pass the function name, or some identifying pattern, or anything else you like, but all on the condition that the receiving code knows how to act on that.

    JSON provides no mechanism for representing a "function". The concept is completely alien to the format, and rightly so, as it's intended to be language-neutral.

    edit — Note that if you encode your function by name:

    <script type="application/json">
    {
        "search": {
            "search_string": "text to be searched",
            "callback": "search_callback_23"
        }
    }
    </script>
    

    Then the code that grabs the object and interprets the contents can always invoke the function with the outer JSON object as the context:

    function handleJSON( the_JSON_from_the_example ) {
      var json = JSON.parse(the_JSON_from_the_example);
      if ("search" in json) {
        var searchTerm = json.search.search_string;
        var callback = findCallbackFunction(json.search.callback); // whatever 
        callback.call(json, searchTerm); // or json.search maybe?
      }
    }
    

    In other words, if the code that's interpreting the JSON-encoded information knows enough to find callback function references, then it can probably figure out an appropriate object to use as this when it calls the function.