2012-03-12 3 views
9

У меня есть строка json, которую я анализирую, а затем доступ к свойствам объекта с помощью точечной нотации. Тем не менее, в компиляторе google, точечная нотация (MyObject.PropertyName) дает предупреждение о том, что свойство не определено.компилятор google закрытия и json

В настоящее время решение, которое я использую, состоит в том, чтобы преобразовать код в скобку (MyObject['PropertyName']). Это устраняет предупреждение, но также не позволяет компилятору выполнять свою работу. С другой стороны, когда я пишу JSON.stringify(MyObject), сервер получает строку с именами свойств, которые понятны.

Итак, мой вопрос в том, как лучше всего использовать компилятор google в расширенном режиме при работе с объектами json, которые десериализуются и сериализуются во время выполнения.

ответ

1

Если только JavaScript, который вы собираетесь писать, это доступ к внешнему json, то он поражает точку использования компилятора. Однако, если у вас есть даже тривиальное количество JavaScript, которое работает, помимо разбора вашего json в моделях домена, тогда компилятор может быть полезен.

В наших анализаторах мы получаем доступ к нашим данным с помощью скобок, чтобы мы могли правильно получить данные. Оттуда мы вводим данные в наши собственные модели, которые мы используем. обозначение сверху. Они дико переименованы, дают нам проверку типов и все это добро.

Редактировать >> Для данных я использую XHRManager. Это очень классный класс. Когда я получаю событие данных из этого пула, я обрабатываю его следующим образом.

/** 
* @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! 
}; 

Я должен предупредить вас, моя обработка XHRManager по-прежнему оставляет желать лучшего. На прошлой неделе я только реорганизовал мой код, чтобы начать использовать его.

Для синтаксического анализа я делаю это: (Это какой-то сырой материал из моего кода базы, так что игнорировать некоторые из некрасиво.)

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. 
    } 
}; 
+0

Вы постоянно сериализовать данные через JSON.stringify и JSON.parse? это крайне неэффективно, какова ваша причина для этого. Мой код не будет иметь для вас тонкости из контекста, но мы отделяем создание модели от синтаксического анализа, используя шаблон построителя http://en.wikipedia.org/wiki/Builder_pattern. Я честно считаю, что ядром вашей проблемы может быть ваше использование stringify + parse, объясните мне, что вы пытаетесь решить с этим. – lennel

+0

Да, я использую собственный сериализатор. Какой вариант лучше? Я где-то читал, что использование библиотеки происходит медленнее, чем использование собственного синтаксического анализа. Объекты приходят и уходят через ajax, а также в локальное хранилище и обратно. – frenchie

+0

Я просто поправил свой комментарий, снова проверил и объяснил мне, почему вы все время используете Json.stringify и Json.parse. – lennel

5

Вы в основном есть два варианта:

  1. использование объектов доступ к массиву с использованием строкового литерала (aka MyJsonObject['PropertyName']) это простое решение.
  2. создать внешний файл, описывающий свойства объекта JSON, а затем использовать точечную нотацию (aka). Это требует большего обслуживания, но позволяет компилятору печатать проверки свойств, если вы указываете аннотации типов в описании extern.
+0

У вас есть какие-то ресурсы, на которые я могу посмотреть, для указания файлов externs? благодаря! –

+1

https://developers.google.com/closure/compiler/docs/api-tutorial3?hl = en # externs Как правило, externs должен быть действительным javascript, но упрощенные декларации: var – John

1

EDIT:@expose директива устарела


Google Closure Compiler позволяет определить директивы о том, как компиляция должна осуществляться через аннотациями.

См: https://developers.google.com/closure/compiler/docs/js-for-compiler

Правильно используя @expose и @type вы можете сохранить имя свойства в коде.

Можно безопасно декодировать строку JSON в объект и получить доступ к этому объекту с использованием точечной нотации. Вы также сможете указать .

-

Давайте сделаем пример:

Вы хотите, чтобы разобрать массив объектов. Каждый объект представляет собой размер « » со свойствами w для ширины и h для высоты.

Объявите прототип для размера объекта и подвергать свои свойства ш и ч

function size() {} 

/** @expose */ 
size.prototype.w = 0; 
/** @expose */ 
size.prototype.h = 0; 

Затем вы хотите поместить JSON синтаксический анализ данных в массив называется данных.

Использование @type вы заявляете, что данные собирается провести массив объекта типа размера.

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(); 
+0

Я не могу найти упоминания '@ expose' на веб-странице, на которую вы указываете. Является ли эта аннотация документирована где-то? – jochen

+0

@jochen директива '@ expose' была удалена из документации. Удивительно даже не упоминается как устаревшее. Кажется, теперь '@ expose' появляется только на некоторых SO-ответах, подобных моим. Я думаю, он по-прежнему поддерживается, чтобы не нарушать устаревший код, но я не проверял. Я все еще использую старую версию компилятора Closure (с момента, когда '@ expose' был зарегистрирован и реализован) – Paolo

+0

' @ expose' теперь официально устарел. –

Смежные вопросы