2012-03-12 34 views
9

Tôi có một chuỗi json mà tôi phân tích cú pháp và sau đó truy cập các thuộc tính của đối tượng bằng ký hiệu chấm. Tuy nhiên, trong trình biên dịch đóng cửa của google, ký hiệu chấm (MyObject.PropertyName) cảnh báo rằng thuộc tính không được xác định.Trình đóng mở google và json

Hiện tại, giải pháp tôi đang sử dụng là chuyển mã của tôi thành ký hiệu khung (MyObject['PropertyName']). Điều này loại bỏ cảnh báo nhưng cũng ngăn cản trình biên dịch thực hiện công việc của nó. Mặt khác, khi tôi viết JSON.stringify(MyObject), máy chủ sẽ nhận được một chuỗi có tên thuộc tính dễ hiểu.

Vì vậy, câu hỏi của tôi là làm thế nào để chúng tôi sử dụng tốt nhất trình biên dịch google ở ​​chế độ nâng cao khi làm việc với các đối tượng json được deserialized và serialized khi chạy.

Trả lời

1

Nếu mã JavaScript duy nhất bạn viết sẽ truy cập vào json bên ngoài, thì nó sẽ đánh bại điểm sử dụng trình biên dịch. Tuy nhiên, nếu bạn thậm chí có một số lượng nhỏ JavaScript không hoạt động ngoài việc phân tích cú pháp json của bạn thành các mô hình miền thì trình biên dịch có thể hữu ích.

Trong trình phân tích cú pháp của chúng tôi, chúng tôi truy cập dữ liệu của chúng tôi thông qua ký hiệu khung để chúng tôi có thể nhận dữ liệu chính xác. Từ đó chúng tôi đưa dữ liệu vào các mô hình của riêng mình, mà chúng tôi sử dụng. ký hiệu trên. Chúng được đổi tên một cách hoang dại, cho chúng ta kiểm tra kiểu và tất cả sự tốt lành đó.

Chỉnh sửa >> Đối với dữ liệu tôi sử dụng XHRManager. Đây là một lớp học nghiêm túc. Khi tôi nhận được một sự kiện dữ liệu từ hồ bơi đó, tôi xử lý nó như sau.

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

Tôi phải cảnh báo bạn, việc xử lý XHRManager của tôi vẫn để lại một chút công bằng mong muốn. Tôi chỉ tái cấu trúc mã của mình tuần trước để bắt đầu sử dụng nó.

Đối với phân tích tôi làm điều này: (Đây là một số công cụ thô từ cơ sở mã của tôi, vì vậy bỏ qua một số xấu xí.)

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

Bạn có thường xuyên tuần tự hóa dữ liệu của mình qua json.stringify và json.parse không? điều này cực kỳ kém hiệu quả, lý do của bạn để làm điều này là gì. Mã của tôi sẽ không tạo ra vô số ý nghĩa với bạn trong bối cảnh, nhưng chúng tôi tách riêng việc tạo mô hình từ phân tích cú pháp bằng cách sử dụng mô hình trình xây dựng http://en.wikipedia.org/wiki/Builder_pattern. Tôi thành thật nghĩ rằng cốt lõi của vấn đề của bạn có thể là bạn sử dụng stringify + phân tích cú pháp, giải thích cho tôi những gì bạn đang hướng tới để giải quyết với điều này. – lennel

+0

Có, tôi sử dụng bộ nối tiếp gốc. Một lựa chọn tốt hơn là gì? Tôi đọc ở đâu đó sử dụng thư viện chậm hơn so với sử dụng phân tích gốc. Các đối tượng đến và đi qua ajax và cũng đến và từ lưu trữ cục bộ. – frenchie

+0

Tôi vừa mới sửa đổi bình luận của tôi, kiểm tra lại và giải thích cho tôi lý do tại sao bạn sử dụng Json.stringify và Json.parse toàn bộ thời gian. – lennel

5

Bạn về cơ bản có hai lựa chọn:

  1. sử dụng đối tượng truy cập mảng bằng cách sử dụng chuỗi ký tự (aka MyJsonObject['PropertyName']) đây là giải pháp đơn giản.
  2. tạo tệp extern mô tả các thuộc tính trong đối tượng JSON của bạn và sau đó sử dụng ký hiệu chấm (aka MyJsonObject.PropertyName). Điều này đòi hỏi phải bảo trì nhiều hơn nhưng cho phép trình biên dịch gõ kiểm tra các thuộc tính nếu bạn cung cấp các chú thích kiểu trong mô tả bên ngoài của bạn.
+0

Bạn có bất kỳ tài nguyên nào mà tôi có thể xem xét để chỉ định tệp externs không? cảm ơn! –

+1

https://developers.google.com/closure/compiler/docs/api-tutorial3?hl = vi # externs Nói chung, externs phải là javascript hợp lệ, nhưng khai báo đơn giản: var – John

1

EDIT: chỉ thị @expose đã bị phản đối


Google Closure Compiler phép bạn chỉ định, chỉ thị về cách biên soạn nên được thực hiện thông qua chú thích.

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

đúng bằng @expose@type bạn có thể duy trì tên của một tài sản trong mã của bạn.

Có thể giải mã một chuỗi JSON thành một đối tượng một cách an toàn và truy cập đối tượng đó bằng cách sử dụng ký hiệu dấu chấm . Bạn cũng có thể xâu chuỗi lại dữ liệu.

-

Hãy làm một ví dụ:

Bạn muốn phân tích một mảng của các đối tượng. Mỗi đối tượng đại diện cho một kích thước ", với các thuộc tính w cho chiều rộng và h cho chiều cao.

Khai báo một nguyên mẫu cho kích thước đối tượng và lộ thuộc tính của nó wh

function size() {} 

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

Sau đó, bạn muốn đặt JSON phân tích dữ liệu vào một mảng gọi dữ liệu.

Sử dụng @type bạn tuyên bố rằng dữ liệu sẽ tổ chức một mảng của đối tượng kiểu kích thước.

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

Tôi không thể tìm thấy bất kỳ đề cập đến '@ expose' trên trang web mà bạn trỏ đến. Chú thích này có được ghi lại ở đâu đó không? – jochen

+0

@jochen chỉ thị '@ expose' đã bị xóa khỏi tài liệu. Đáng ngạc nhiên là thậm chí không được đề cập là không được chấp nhận. Có vẻ như bây giờ '@ expose' chỉ xuất hiện trên một số câu trả lời SO, giống như tôi. Tôi đoán nó vẫn được hỗ trợ để tránh phá vỡ mã di sản nhưng tôi đã không kiểm tra. Tôi vẫn đang sử dụng phiên bản cũ của Trình biên dịch đóng cửa (từ một thời điểm '@ expose' đã được ghi lại và triển khai) – Paolo

+0

' @ expose' hiện đã không còn được dùng nữa. –