开发者

3rd Party JSON with Google Closure in Advanced Mode?

I'm having trouble with the advanced optimization of the closure compiler trying to rename my JSON properties. I am using the rich autocomplete control and feeding it with JSON returned from my action that contains contacts with Name and Phone properties. The Closure compiler is renaming Name and Phone in my methods and templates. In the method I can get around it by using the property name as a string key into the object, but I don't know how to do that with templates:

/**
 * @param {{Name: string, Phone: string}} item Item returned for autocomplete
 */
example.makeRow = function (item) {
    item.render = function (node, token) {
        // item.Phone + '</div>' + '<div style="float: right">' + item.Name;
        node.innerHTML = template.autocomplete(item); 
    }
}

My JSON object has the full names of the properties "Name" and "Phone" but the function re-writes them to something like "Hx" and "Az". Ditto for my template:

{namespace template}

/**
 * Single row in the example autocomplete box.
 * @param Phone Contact's phone number
 * @param Name Contact's full name
 */
{template .autocomplete}
{$Phone}<span style="padding-left: 15px">{$Name}
{/template}

If I add these two lines to the start of the makeRow function, it sets the condensed names to the proper values from the original names:

item.Name = item['Name'];
item.Phone = item['Phone'];

Doing this seems wasteful both space-wise and performance-wise. Also I have no intention of doing this for all my JSON objects, I plan on having a lot in my applications in the future (this is just a simple test). I don't have a clue how to map the new names to the old. I can create a sourcemap, but there are just a bunch of numbers and I don't know what they mean. If I could figure out that then maybe I could write an easy property mapper in C# to create dynamic objects with the shortened names.

If I have to use simple optimization mode that would such hard given the lengthy names of all the objects and properties in the closure library. It should be SIMPLE. I think it woul开发者_如何学运维d be great if they had a @json tag instead of @param that would prevent renaming, or some other signal for the @param to not rename the object's properties:

 * @param {{Name: string, Phone: string}} item Item returned for autocomplete

would become

 * @json {{Name: string, Phone: string}} item Item returned for autocomplete

I found that I can make the property names stay the same by creating an externs.js file and specifying it at compile time:

var foo = {};
foo.Name = null;
foo.Phone = null;

I think that ANY object properties with those names will then not be compressed, is that true? I guess I could write some helpers to produce the long list of property names given the classes I will use. Also I might like to use dynamic types for some things and am afraid I might forget or misspell a property name.


EDIT:

Not something the project wants to support, they recommend taking the object as a parameter like this:

{namespace template}

/**
 * Single row in the example autocomplete box.
 * @param json Object with actual values
 */
{template .autocomplete}
{$json['Phone']}<span style="padding-left: 15px">{$json['Name']}
{/template}


The closest thing which Closure supports is an extern. Simply create an extern for your JSON object, pass it to the compiler and everything will work as you wish. Here's a basic example for your case:

/** @constructor */
function AutoCompleteItem() {}

/** @type {string} */
AutoCompleteItem.prototype.Name;

/** @type {string} */
AutoCompleteItem.prototype.Phone;

Note that it is common and quite acceptable to just access JSON properties using bracket syntax (object['Name']) -- this will compile to object.Name in the final output, and avoids having to create the extern.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜