简体   繁体   English

谷歌闭包编译器和json

[英]google closure compiler and json

I have a json string that I parse and then access the properties of the object with the dot notation. 我有一个json字符串,我解析,然后用点表示法访问对象的属性。 However, in the google closure compiler, the dot notation ( MyObject.PropertyName ) gives warning that the property isn't defined. 但是,在谷歌闭包编译器中,点表示法( MyObject.PropertyName )会发出警告,表明未定义该属性。

For now, the solution I'm using is to convert my code into bracket notation ( MyObject['PropertyName'] ). 目前,我正在使用的解决方案是将我的代码转换为括号表示法( MyObject['PropertyName'] )。 This removes the warning but also prevents the compiler from doing its job. 这将删除警告,但也会阻止编译器执行其工作。 On the other hand, when I write JSON.stringify(MyObject) , the server receives a string with property names that are understandable. 另一方面,当我编写JSON.stringify(MyObject) ,服务器会收到一个字符串,其属性名称是可以理解的。

So my question is how do we best use the google compiler in advanced mode when working with json objects that are deserialized and serialized at runtime. 所以我的问题是在处理运行时反序列化和序列化的json对象时,如何在高级模式下最好地使用google编译器。

You basically have two choices: 你基本上有两个选择:

  1. use object array access using the string literal (aka MyJsonObject['PropertyName'] ) this is the simple solution. 使用字符串文字(又名MyJsonObject['PropertyName'] )使用对象数组访问这是一个简单的解决方案。
  2. create a extern file describing the properties in your JSON object and then use dot notation (aka MyJsonObject.PropertyName ). 创建一个描述JSON对象属性的extern文件,然后使用点表示法(又名MyJsonObject.PropertyName )。 This requires more maintenance but allows the compiler to type check the properties if you provide type annotations in your extern description. 这需要更多维护,但如果您在extern描述中提供类型注释,则允许编译器键入检查属性。

EDIT: the @expose directive has been deprecated 编辑: @expose指令已被弃用


Google Closure Compiler lets you specify directives on how compilation should be done through annotations . Google Closure Compiler允许您指定如何通过注释进行编译的指令。

See: https://developers.google.com/closure/compiler/docs/js-for-compiler 请参阅: https//developers.google.com/closure/compiler/docs/js-for-compiler

Properly using @expose and @type you can preserve the name of a property in your code. 正确使用@expose@type,您可以在代码中保留属性的名称。

It is possible to safely decode a JSON string into an object and access that object using the dot notation. 可以将JSON字符串安全地解码为对象,并使用点表示法访问该对象。 You'll be also able to stringify back the data. 您还可以对数据进行字符串化。

- -

Let's make an example: 我们举一个例子:

You want to parse an array of objects. 您想要解析一个对象数组。 Every object represents a "size", with the properties w for width and h for height. 每个对象代表一个“大小”,其中w为宽度, h为高度。

Declare a prototype for the size object and expose its properties w and h 声明size对象的原型并公开其属性wh

 function size() {} /** @expose */ size.prototype.w = 0; /** @expose */ size.prototype.h = 0; 

Then you want to put the JSON parsed data into an array called data . 然后,您希望将JSON解析数据放入名为data的数组中。

Using @type you declare that data is going to hold an array of object of type size . 使用@type,您声明数据将包含一个类型为size的对象数组

 function main() { /** @type {Array.<size>} */ var data; // string built up just for example purposes var response = '[{"w": 10, "h": 20}]'; // parse the array var data = JSON.parse(response); // access data with dot notation! console.log(data[0].w+ " "+ data[0].h); } main(); 

If the only JavaScript you are going to write is accessing external json, then it defeats the point of using the compiler. 如果您要编写的唯一JavaScript是访问外部json,那么它就无法使用编译器。 However, if you have even a trivial amount of JavaScript which does work besides parsing your json into domain models then the compiler may be useful. 但是,如果除了将json解析为域模型之外,如果你还有一些微不足道的JavaScript,那么编译器可能会很有用。

In our parsers we access our data via bracket notation so we can get the data properly. 在我们的解析器中,我们通过括号表示法访问我们的数据,以便我们可以正确获取数据。 From there we stuff the data into our own models, which we use the . 从那里我们将数据填充到我们自己的模型中,我们使用它们。 notation on. 符号。 These get wildly renamed, gives us type checking and all of that goodness. 这些被大量重命名,给我们进行类型检查和所有这些优点。

Edit>> For data I use the XHRManager . 编辑>>对于数据,我使用XHRManager This is one seriously nice class. 这是一个非常好的课程。 When I get a data event from that pool I handle it as follows. 当我从该池中获取数据事件时,我按如下方式处理它。

/**
 * @private
 * @param {goog.events.Event} evt The event recieved from the XhrIo.
 */
mypath.MyClass.prototype.onDataRecieved_ = function(evt) {
  if (evt.type != 'complete') return;
  var xhrIo = evt.target;
  var data = xhrIo.getResponseJson();
  //do somethign!
};

I have to warn you, my XHRManager handling still leaves a fair bit to be desired. 我必须警告你,我的XHRManager处理仍然有待改进。 I only refactored my code last week to start using it. 我上周才重构我的代码才开始使用它。

For parsing I do this: (This is some raw stuff from my code base, so ignore some of the ugly.) 对于解析我这样做:(这是我的代码库中的一些原始内容,所以忽略一些丑陋。)

our.class.path.ContestJsonParser.prototype.setContestProperties =
    function(contest, element) {
  contest.setName(element['description']);
  /**
     * @type {!number}
     */
  var timeAsInt = element['startTime'];
  contest.setScheduledStartTime(timeAsInt);
  var clockModel = contest.getClockModel();
  if (goog.isDefAndNotNull(element['period'])) {
    clockModel.setMatchState(element['period']['periodName']);
    clockModel.setStateStartTime(element['period']['periodStartTime']);
  }
  //TODO (Johan) this needs to change today to consider the rest of the stats
  //information
  var stats = element['statistics'];
  if (goog.isObject(stats) && goog.isDefAndNotNull(stats['score'])) {
    var score = stats['score'];
    contest.setMatchScore(score['home'], score['away']);
  } else {
    contest.setMatchScore(undefined, undefined); // clears score.
  }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM