Sử dụng Thư viện ứng dụng JavaScript (v2.0)

Cảnh báo: Trang này giới thiệu về các API cũ của Google, API dữ liệu của Google; trang này chỉ liên quan đến các API được liệt kê trong thư mục API dữ liệu của Google, nhiều API trong số này đã được thay thế bằng các API mới hơn. Để biết thông tin về một API mới cụ thể, hãy xem tài liệu của API mới. Để biết thông tin về việc uỷ quyền cho các yêu cầu bằng một API mới hơn, hãy xem phần Xác thực và ủy quyền tài khoản Google.

Tài liệu này mô tả cách sử dụng thư viện ứng dụng JavaScript để gửi các truy vấn API Dữ liệu của Google và diễn giải các phản hồi được trả về.

Google cung cấp một bộ thư viện ứng dụng, bằng nhiều ngôn ngữ lập trình, để tương tác với các dịch vụ có API dữ liệu. Khi sử dụng các thư viện này, bạn có thể xây dựng các yêu cầu API, gửi các yêu cầu đó đến một dịch vụ và nhận phản hồi.

Tài liệu này cung cấp một số thông tin chung về cách sử dụng thư viện ứng dụng JavaScript, cùng với một tập hợp các ví dụ về cách sử dụng phổ biến.

Đối tượng người xem

Tài liệu này dành cho các lập trình viên JavaScript muốn viết ứng dụng khách có thể tương tác với dịch vụ Dữ liệu của Google.

Tài liệu này giả định rằng bạn hiểu các ý tưởng chung đằng sau giao thức API dữ liệu của Google. Phần này cũng giả định rằng bạn biết cách lập trình trong JavaScript.

Để biết thông tin tham khảo về các lớp và phương thức do thư viện ứng dụng cung cấp, hãy xem tài liệu tham khảo API về thư viện ứng dụng JavaScript (ở định dạng JSdoc).

Tài liệu này được thiết kế để đọc theo thứ tự; mỗi ví dụ được xây dựng dựa trên các ví dụ trước đó.

Điều khoản sử dụng

Bạn đồng ý tuân thủ Điều khoản sử dụng Thư viện JavaScript của Google khi sử dụng thư viện ứng dụng JavaScript.

Tổng quan về mô hình dữ liệu và luồng kiểm soát

Thư viện ứng dụng JavaScript sử dụng một tập hợp các lớp để đại diện cho các thành phần mà API dữ liệu của Google sử dụng.

Lưu ý: Cách biểu diễn cơ bản của dữ liệu là JSON, nhưng thư viện ứng dụng cung cấp lớp trừu tượng để bạn không phải làm việc trực tiếp với dữ liệu JSON. Nếu bạn muốn làm việc trực tiếp với JSON mà không cần thư viện ứng dụng, hãy xem phần Sử dụng JSON với API dữ liệu của Google.

Thư viện này cung cấp các phương thức cho phép bạn gửi dữ liệu đến và nhận không đồng bộ từ dữ liệu của một dịch vụ có API dữ liệu. Ví dụ: phương thức google.gdata.calendar.CalendarService.getEventsFeed() sẽ gửi yêu cầu về nguồn cấp dữ liệu tới Lịch Google. Một trong các tham số bạn truyền là hàm tiếp tục, còn gọi là lệnh gọi lại; dịch vụ trả về nguồn cấp dữ liệu, ở định dạng JSON, bằng cách gọi hàm tiếp tục. Sau đó, ứng dụng có thể gọi nhiều phương thức get để sử dụng dữ liệu dưới dạng các đối tượng JavaScript.

Để thêm mục nhập mới, bạn tạo mục nhập bằng cách sử dụng các lớp và phương thức của thư viện ứng dụng, sau đó gọi phương thức feed.insertEntry() để gửi mục nhập mới đến dịch vụ. Xin nhắc lại rằng bạn cung cấp một hàm tiếp tục mà dịch vụ gọi sau khi bạn đã thêm thành công mục nhập.

Nếu bạn mới sử dụng JavaScript, quy trình kiểm soát có thể hơi khó hiểu. Sau khi gọi một phương thức như getEventsFeed() hoặc insertEntry(), trong hầu hết trường hợp, tập lệnh của bạn sẽ kết thúc. Việc thực thi sẽ tiếp tục trong hàm tiếp tục khi dịch vụ trả về dữ liệu được yêu cầu. Do đó, mọi việc mà ứng dụng của bạn thực hiện đối với dữ liệu được trả về phải được thực hiện trong hàm tiếp tục hoặc được gọi từ hàm đó. Bạn có thể phải đặt một số biến trên toàn cục để sử dụng chúng trong nhiều hàm.

Để biết thêm thông tin về kiểu lập trình này, hãy xem "Kiểu chuyển tiếp" trên Wikipedia.

Giới thiệu về các môi trường được hỗ trợ

Hiện tại, chúng tôi chỉ hỗ trợ các ứng dụng khách JavaScript chạy trong một trang web trong trình duyệt. Hiện tại, các trình duyệt được hỗ trợ là:

  • Firefox 2.x và 3.x
  • Internet Explorer 6, 7 và 8
  • Safari 3.x & amp; 4.x
  • Google Chrome (tất cả phiên bản)

Thư viện ứng dụng JavaScript sẽ xử lý tất cả các hoạt động giao tiếp với máy chủ của dịch vụ. Nếu là một nhà phát triển JS có kinh nghiệm, bạn có thể nghĩ: "Nhưng còn cùng một chính sách về nguồn gốc thì sao?" Thư viện ứng dụng JavaScript cho phép ứng dụng của bạn gửi yêu cầu Dữ liệu Google từ bất kỳ miền nào trong khi vẫn tuân thủ mô hình bảo mật của trình duyệt.

Để biết thông tin tổng quan về cách xác thực bằng API Google Data, hãy xem Tổng quan về xác thực API dữ liệu của Google. Phần còn lại của tài liệu này giả định rằng bạn đã quen thuộc với những kiến thức cơ bản về cách hoạt động của hệ thống này.

Ứng dụng mẫu

Để xem thư viện ứng dụng JavaScript hoạt động, hãy truy cập trang mẫu của chúng tôi.

Hướng dẫn và ví dụ

Các ví dụ sau đây minh họa cách gửi nhiều yêu cầu về API dữ liệu bằng cách sử dụng thư viện ứng dụng JavaScript.

Để giúp họ cụ thể hơn, những ví dụ này cho thấy cách tương tác với một dịch vụ cụ thể: Lịch Google. Chúng tôi sẽ chỉ ra những điểm khác biệt giữa Lịch và các dịch vụ khác của Google để giúp bạn điều chỉnh các ví dụ này cho phù hợp với các dịch vụ khác. Để biết thêm thông tin về Lịch, hãy xem tài liệu về API Dữ liệu của Lịch Google.

Đang tải thư viện

Trước khi ứng dụng có thể sử dụng thư viện ứng dụng, ứng dụng khách phải yêu cầu mã thư viện ứng dụng từ máy chủ.

Bắt đầu bằng cách sử dụng thẻ <script> trong phần <head> của tài liệu HTML của bạn để tìm nạp trình tải API AJAX của Google:

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

Bạn có thể giảm thiểu việc trọn vòng đến máy chủ của Google và giảm độ trễ bằng cách tải trước thư viện. Để tải trước một số gói nhất định trực tiếp từ trình tải API Google AJAX (mà không sử dụng google.load() như bên dưới), hãy sử dụng:

<script type="text/javascript"
      src="https://www.google.com/jsapi?autoload=%7Bmodules%3A%5B%7Bname%3Agdata%2Cversion%3A2.x%2Cpackages%3A%5Bblogger%2Ccontacts%5D%7D%5D%7D"></script>

Lưu ý: URL src của tập lệnh phải được mã hoá URL hoàn toàn. Ví dụ: ví dụ trước là
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={modules:[{name:gdata,version:2.x,packages:[blogger,contacts]}]}"></script>.

Nếu không tự động tải các mô-đun, bạn có thể tải thư viện ứng dụng Google Data bằng cách sử dụng ví dụ tiếp theo trong mã thiết lập JavaScript, sau khi tìm nạp trình tải chung. Lệnh gọi này phải được thực hiện từ phần <head> của tài liệu HTML (hoặc từ tệp JavaScript có trong thẻ <script> trong phần <head> của tài liệu HTML):

google.load("gdata", "2");

Ngoài ra, bạn có thể yêu cầu các dịch vụ cụ thể thay vì toàn bộ thư viện. Ví dụ này chỉ tải các gói của Blogger và Danh bạ xuống:

google.load("gdata", "2.x", {packages: ["blogger", "contacts"]});

Thông số thứ hai cho google.load() là số phiên bản yêu cầu của thư viện ứng dụng JavaScript.Lược đồ đánh số phiên bản của chúng tôi được lập mô hình sau lược đồ được API Google Maps sử dụng. Dưới đây là các số phiên bản có thể có và ý nghĩa của chúng:

"1"
Bản sửa đổi thứ hai đến cuối của phiên bản chính 1.
"1.x"
Bản sửa đổi mới nhất của phiên bản chính 1.
"1.s"
Bản sửa đổi ổn định mới nhất cho phiên bản chính 1. Đôi khi, chúng tôi sẽ khai báo một phiên bản nhất định của thư viện ứng dụng là "ổn định" dựa trên ý kiến phản hồi mà chúng tôi nhận được từ nhà phát triển. Tuy nhiên, phiên bản đó có thể không có các tính năng mới nhất.
"1.0", "1.1", v.v.
Phiên bản thư viện cụ thể có số lượng bản sửa đổi lớn và nhỏ được chỉ định.

Sau khi gọi google.load(), bạn phải yêu cầu trình tải chờ cho đến khi trang tải xong rồi gọi mã của bạn:

google.setOnLoadCallback(getMyFeed);

Trong đó getMyFeed() là một hàm được xác định trong phần tiếp theo của tài liệu này. Hãy sử dụng phương pháp này thay vì đính kèm trình xử lý onload vào phần tử <body>.

Yêu cầu nguồn cấp dữ liệu chưa được xác thực

Để yêu cầu nguồn cấp dữ liệu chưa được xác thực, hãy thêm mã sau vào tệp JavaScript hoặc vào một thẻ <script> trong tệp HTML của bạn.

Trong mã sau, getMyFeed() được gọi trước (bằng trình tải API AJAX, như được mô tả trong phần trước).

Phương thức này gọi setupMyService() để tạo kết nối (được biểu thị bằng đối tượng CalendarService) vào Lịch Google. Chúng tôi đã kéo mã tạo dịch vụ vào một hàm riêng biệt dành cho mô-đun; sau này, chúng tôi sẽ sửa đổi hàm setupMyService(), tùy thuộc vào lựa chọn xác thực của bạn.

Sau khi thiết lập dịch vụ, getMyFeed() sẽ gọi phương thức getEventsFeed() của thư viện ứng dụng để yêu cầu nguồn cấp dữ liệu.

Chúng tôi đang chỉ định URL của nguồn cấp dữ liệu trong một biến toàn cục để có thể dùng trong các hàm sau. Trong ví dụ này, chúng tôi đang sử dụng URL nguồn cấp dữ liệu công khai (chưa được xác thực) của một người dùng có tên là liz@gmail.com. Bạn cũng có thể dùng default thay cho địa chỉ email của người dùng đó để đại diện cho người dùng đã được xác thực.

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/public/full";

function setupMyService() {
  var myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
  return myService;
}

function getMyFeed() {
  myService = setupMyService();

  myService.getEventsFeed(feedUrl, handleMyFeed, handleError);
}

Lưu ý rằng chúng ta sẽ tạo myService thành biến toàn cục để dễ sử dụng trong các hàm sau.

Để làm cho mã ở trên hoạt động trong ứng dụng của riêng bạn, bạn phải sử dụng địa chỉ email của người dùng thực cho tài khoản Lịch có lịch được chia sẻ công khai.

Lưu ý: Khi bạn tạo một đối tượng CalendarService mới, thư viện ứng dụng sẽ gọi một phương thức có tên google.gdata.client.init(). Phương thức này kiểm tra xem trình duyệt mà ứng dụng đang chạy có được hỗ trợ hay không. Nếu xảy ra lỗi, thư viện ứng dụng sẽ hiển thị thông báo lỗi cho người dùng. Nếu muốn tự xử lý loại lỗi này, bạn có thể gọi google.gdata.client.init(handleInitError) một cách rõ ràng trước khi tạo dịch vụ, trong đó handleInitError() là hàm của bạn. Nếu xảy ra lỗi khởi đầu, thì hàm của bạn sẽ nhận được một đối tượng Lỗi chuẩn; bạn có thể làm bất cứ điều gì mình muốn với đối tượng đó.

Trong lệnh gọi đến getEventsFeed(), đối số thứ hai là handleMyFeed, là một hàm callback; xem bên dưới. Lịch Google xử lý yêu cầu và sau đó, nếu yêu cầu thành công, chuyển đối tượng "nguồn cấp dữ liệu" chứa nguồn cấp dữ liệu được yêu cầu đến lệnh gọi lại. Gốc nguồn cấp dữ liệu là một đối tượng vùng chứa chứa nguồn cấp dữ liệu.

Đối số thứ ba cho getEventsFeed() là một hàm xử lý lỗi không bắt buộc; nếu thư viện ứng dụng gặp lỗi, sẽ gọi trình xử lý lỗi được chỉ định thay vì hàm gọi lại thành công. Đối tượng mà thư viện ứng dụng truyền làm đối số cho trình xử lý lỗi là một thực thể của JavaScript Error đối tượng, với một thuộc tính cause bổ sung.

Dưới đây là các phiên bản đơn giản của hàm callback và trình xử lý lỗi:

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
}

function handleError(e) {
  alert("There was an error!");
  alert(e.cause ? e.cause.statusText : e.message);
}

Chúng tôi đang xử lý lỗi bằng cách chỉ hiển thị lỗi cho người dùng; trình xử lý lỗi của khách hàng có thể sẽ phải phức tạp hơn. Trong một số bối cảnh, có thể không có nguyên nhân nào được chỉ định, vì vậy trong những trường hợp đó, trình xử lý lỗi của chúng tôi sẽ quay lại hiển thị thuộc tính message chuẩn.

Xin lưu ý rằng vì mã này không thực hiện quy trình xác thực nên bạn chỉ có thể sử dụng mã này để lấy nguồn cấp dữ liệu công khai.

Đang xác thực

Bạn có thể sử dụng thư viện ứng dụng JavaScript ở hai chế độ. Nếu bạn đang viết một tiện ích, tiện ích đó sẽ sử dụng tính năng được gọi là Proxy OAuth để xác thực. Nếu đang được truy cập từ một ứng dụng JavaScript độc lập, ứng dụng đó sẽ sử dụng hệ thống xác thực AuthSub. Để biết thông tin về quy trình xác thực, hãy xem tài liệu Tổng quan về quy trình xác thực API dữ liệu của Google. Phần còn lại của phần này giả định rằng bạn đã quen thuộc với các khái niệm cơ bản về cách hoạt động của hệ thống này.

Trước khi sử dụng tính năng xác thực với mã mẫu được cung cấp trong tài liệu này, hãy thay đổi URL nguồn cấp dữ liệu từ công khai thành riêng tư:

var feedUrl = "http://www.google.com/calendar/feeds/liz@gmail.com/private/full";

Xác thực trong một ứng dụng web bằng AuthSub

Hệ thống uỷ quyền "AuthSub cho JavaScript" của Google không còn hoạt động nữa.

Thay vào đó, bạn nên dùng OAuth 2.0 cho ứng dụng phía máy khách.

Xác thực trong một Tiện ích với Proxy OAuth

Dưới đây là tổng quan ngắn gọn về những gì xảy ra trong quá trình xác thực cho một tiện ích:

  1. Tiện ích của bạn tải lần đầu tiên và cố gắng truy cập vào dữ liệu của người dùng bằng một trong các API Dữ liệu của Google.
  2. Yêu cầu không thành công vì người dùng chưa cấp quyền truy cập vào dữ liệu của họ. Đối tượng phản hồi chứa URL (trong response.oauthApprovalUrl) cho trang phê duyệt OAuth. Tiện ích của bạn phải cung cấp phương thức để khởi chạy một cửa sổ mới với URL đó.
  3. Trên trang phê duyệt, người dùng chọn cấp/từ chối quyền truy cập vào tiện ích của bạn. Nếu thành công, người dùng sẽ được chuyển đến trang oauth_callback mà bạn chỉ định. Để có trải nghiệm người dùng tốt nhất, hãy sử dụng http://oauth.gmodules.com/gadgets/oauthcallback.
  4. Tiếp theo, người dùng đóng cửa sổ bật lên. Để giúp thông báo cho tiện ích của bạn rằng người dùng đã phê duyệt, chúng tôi đã cung cấp trình xử lý bật lên mà bạn có thể dùng để phát hiện việc đóng cửa sổ phê duyệt. Ngoài ra, tiện ích của bạn có thể hiển thị một đường liên kết (ví dụ: "Tôi đã phê duyệt quyền truy cập") để người dùng nhấp vào theo cách thủ công sau khi cửa sổ này đóng lại.
  5. Tiện ích của bạn cố gắng truy cập Google Data API lần thứ hai bằng cách yêu cầu lại dữ liệu của người dùng. Bạn đã thử xong.
  6. Tiện ích của bạn được xác thực và có thể bắt đầu hoạt động bình thường.

Trong tiện ích của bạn, hãy thêm một phần tử <OAuth> trong phần <ModulePrefs>:

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?
                  scope=http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

Trong mục này, hãy thay đổi các tham số truy vấn sau đây:

  • scope

    Một tham số bắt buộc trong URL yêu cầu. Tiện ích của bạn sẽ chỉ có thể truy cập vào dữ liệu từ(các) scope được dùng trong thông số này. Trong ví dụ này, tiện ích sẽ truy cập vào dữ liệu Blogger và Lịch của bạn. Một tiện ích có thể yêu cầu dữ liệu cho một phạm vi hoặc nhiều phạm vi (như ví dụ này đã làm).

  • oauth_callback

    Một tham số không bắt buộc trong URL uỷ quyền. Trang phê duyệt OAuth sẽ chuyển hướng đến URL này sau khi người dùng đã phê duyệt quyền truy cập vào dữ liệu của họ. Bạn có thể chọn bỏ thông số này, đặt thông số này thành "trang được phê duyệt" của riêng mình hoặc tốt nhất là sử dụng http://oauth.gmodules.com/gadgets/oauthcallback. Phiên bản sau này cung cấp trải nghiệm người dùng tốt nhất khi người dùng cài đặt tiện ích của bạn lần đầu tiên. Trang đó cung cấp một đoạn mã JavaScript tự động đóng cửa sổ bật lên đó.

Tiếp theo, tải thư viện ứng dụng JavaScript vào phần <Content> của tiện ích. Sửa đổi hàm setupMyService() từ các ví dụ trước để gọi phương thức useOAuth() của đối tượng dịch vụ. Điều này yêu cầu tiện ích sử dụng Proxy OAuth để xác thực thay vì AuthSub. Mẫu dưới đây sẽ giúp bạn bắt đầu:

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
    var myService = null;
    
    function setupMyService() {
      myService = new google.gdata.calendar.CalendarService('exampleCo-exampleApp-1');
      myService.useOAuth('google');
      fetchData();
    }
    
    function initGadget() {
      google.load('gdata', '2.x');
      google.setOnLoadCallback(setupMyService);
    }

    function fetchData() {            
      var callback = function(response) {
        if (response.oauthApprovalUrl) {
        
          // TODO: Display "Sign in" link (response.oauthApprovalUrl contains the URL) 
          
        } else if (response.feed) {
        
          // TODO: show results
          
        } else {
        
          // TODO: handle the error
          
        }
      };

      myService.getEventsFeed('http://www.google.com/calendar/feeds/default/public/full', callback, callback);
    }
    
    gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

Lưu ý rằng lệnh gọi đến google.accounts.user.login(scope) đã bị loại bỏ. Proxy xử lý việc xác thực cho bạn.

Để biết thêm thông tin về cách viết các tiện ích API Dữ liệu của Google, bao gồm cả thông tin chi tiết về những gì fetchData() có thể xem, hãy xem bài viết của chúng tôi về việc Tạo một Tiện ích dữ liệu của Google hoặc xem tài liệu đầy đủ về Tiện ích OAuth viết.

Chèn một mục mới

Để tạo một sự kiện mới trên lịch, hãy tiếp tục thực thi trong ví dụ trước bằng cách sửa đổi phần cuối hàm handleMyFeed() để gọi một hàm mới:

function handleMyFeed(myResultsFeedRoot) {
  alert("This feed's title is: " + myResultsFeedRoot.feed.getTitle().getText());
  insertIntoMyFeed(myResultsFeedRoot);
}

Trong hàm mới này, trước tiên hãy dùng hàm khởi tạo CalendarEventEntry để tạo mục nhập mới. Sau đó, hãy chèn mục nhập, cung cấp một lệnh gọi lại để dịch vụ gọi khi chèn xong.

function insertIntoMyFeed(feedRoot) {
  var newEntry = new google.gdata.calendar.CalendarEventEntry({
      authors: [{
        name: "Elizabeth Bennet",
        email: "liz@gmail.com"
      }],
      title: {
        type: 'text', 
        text: 'Tennis with Darcy'
      },
      content: {
        type: 'text', 
        text: 'Meet for a quick lesson'
      },
      locations: [{
        rel: "g.event",
        label: "Event location",
        valueString: "Netherfield Park tennis court"
      }],
      times: [{
        startTime: google.gdata.DateTime.fromIso8601("2007-09-23T18:00:00.000Z"),
        endTime: google.gdata.DateTime.fromIso8601("2007-09-23T19:00:00.000Z")
      }]
  });
  feedRoot.feed.insertEntry(newEntry, handleMyInsertedEntry, handleError);
}

Hãy lưu ý rằng tên của từng thuộc tính đối tượng dùng trong hàm dựng sẽ khớp với tên của phương thức setter dùng cho thuộc tính đó. (Ví dụ: thay vì khớp với tên trường JSON tương ứng.)

Ngoài ra, xin lưu ý rằng bạn không thể chỉ cung cấp chuỗi ngày và giờ ISO 8601 cho startTimeendTime; mà bạn phải chạy các chuỗi đó thông qua phương thức fromIso8601() trước.

Dịch vụ sẽ trả về bản sao của mục nhập đã chèn dưới dạng đối tượng entryRoot, và chuyển đối tượng đó đến lệnh gọi lại:

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
}

Yêu cầu mục nhập cụ thể

Để yêu cầu một mục nhập cụ thể, trước tiên, hãy sửa đổi hàm handleMyInsertedEntry() để gọi một hàm yêu cầu mục nhập mới:

function handleMyInsertedEntry(insertedEntryRoot) {
  alert("Entry inserted. The title is: " + insertedEntryRoot.entry.getTitle().getText());
  alert("The timestamp is: " + insertedEntryRoot.entry.getTimes()[0].startTime);
  requestMySpecificEntry(insertedEntryRoot.entry.getSelfLink().getHref());
}

Mã sau đây cho phép bạn yêu cầu mục nhập cụ thể mà bạn đã chèn vào ví dụ trước.

Trong ngữ cảnh của chuỗi ví dụ này, việc truy xuất mục nhập đó không thực sự cần thiết vì Lịch đã trả về mục nhập được chèn; nhưng kỹ thuật tương tự có thể được áp dụng bất cứ khi nào bạn biết URI cho một mục nhập.

function requestMySpecificEntry(entryURI) {
  myService.getEventsEntry(entryURI, handleMySpecificEntry, handleError);
}

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
}

Về cơ bản, ví dụ này giống với ví dụ về getEventsFeed(), ngoại trừ việc chúng ta đang gọi phương thức getEventEntry() của dịch vụ để nhận một mục nhập cụ thể và URI hơi khác một chút. URI này sử dụng "mặc định" để tham chiếu đến lịch chính của người dùng đã xác thực và có mã mục nhập ở cuối.

Ngoài ra, chúng ta cần có thể sử dụng mục nhập đã truy xuất sau này, vì vậy, chúng ta sẽ sao chép mục đó vào một biến toàn cục.

Đang tìm kiếm các mục nhập

Để tìm kiếm toàn bộ văn bản, trước tiên, hãy sửa đổi hàm handleMySpecificEntry() để gọi một hàm tìm kiếm mới:

function handleMySpecificEntry(retrievedEntryRoot) {
  myEntryRoot = retrievedEntryRoot; // Global variable for later use
  alert("This entry's title is: " + retrievedEntryRoot.entry.getTitle().getText());
  searchMyFeed();
}

Sau đó, để truy xuất kết quả phù hợp đầu tiên từ tìm kiếm, hãy sử dụng mã sau:

function searchMyFeed() {
  var myQuery = new google.gdata.calendar.CalendarEventQuery(feedUrl);
  myQuery.setFullTextQuery("Tennis");
  myQuery.setMaxResults(10);
  myService.getEventsFeed(myQuery, handleMyQueryResults, handleError);
}

function handleMyQueryResults(myResultsFeedRoot) {
  if (myResultsFeedRoot.feed.getEntries()[0]) {
    alert("The first search-match entry's title is: " + myResultsFeedRoot.feed.getEntries()[0].getTitle().getText());
  }
  else {
    alert("There are no entries that match the search query.");
  }
}

Cập nhật một mục

Để cập nhật một mục hiện có, trước tiên, hãy thêm một dòng vào cuối handleMyQueryResults() để gọi một hàm cập nhật mới:

  updateMyEntry();

Sau đó, hãy sử dụng mã sau. Trong ví dụ này, chúng tôi sẽ thay đổi tiêu đề của mục nhập đã truy xuất trước đó (chứa trong đối tượng toàn cầu có tên myEntryRoot trong ví dụ trước) từ văn bản cũ ("Quần vợt có Darcy") thành "Cuộc họp quan trọng".

function updateMyEntry() {
  myEntryRoot.entry.getTitle().setText("Important meeting");
  myEntryRoot.entry.updateEntry(handleMyUpdatedEntry, handleError);
}

function handleMyUpdatedEntry(updatedEntryRoot) {
  alert("Entry updated. The new title is: " + updatedEntryRoot.entry.getTitle().getText());
}

Giống như tất cả các phương thức Lịch, phương thức updateEntry() tự động xác định URI chỉnh sửa chính xác để sử dụng trong việc cập nhật mục nhập, vì vậy bạn không phải cung cấp URI đó một cách rõ ràng.

Xoá một mục

Để xóa mục nhập đã cập nhật, trước tiên, hãy thêm một dòng vào handleMyUpdatedEntry():

 deleteMyEntry(updatedEntryRoot);

Sau đó, hãy sử dụng mã sau:

function deleteMyEntry(updatedEntryRoot) {
  updatedEntryRoot.entry.deleteEntry(handleMyDeletedEntry, handleError);
}

function handleMyDeletedEntry() {
  alert("Entry deleted");
}

Xin nhắc lại, phương thức deleteEntry() tự động xác định đúng URI chỉnh sửa để xoá mục nhập đó.

Xin lưu ý rằng không có mục nào được trả về. Nếu lệnh gọi lại được gọi, thì chúng ta sẽ biết rằng thao tác xoá đã thành công. Nếu xoá không thành công, deleteEntry() sẽ gọi handleError() thay vì gọi handleMyDeletedEntry().

Sử dụng thẻ điện tử

Lưu ý: Bạn chỉ có thể sử dụng ETag với các dịch vụ chạy Giao thức dữ liệu Google phiên bản 2.0.

Giới thiệu

Ứng dụng JavaScript của Google Data phiên bản 2 giới thiệu hỗ trợ cho ETag. ETag là giá trị nhận dạng chỉ định một phiên bản cụ thể của một mục cụ thể; điều này rất quan trọng trong hai trường hợp:

  • Thực hiện "truy xuất có điều kiện", trong đó máy khách yêu cầu một mục nhập và máy chủ chỉ gửi mục nhập nếu mục đó đã thay đổi kể từ lần cuối cùng máy khách yêu cầu.
  • Đảm bảo rằng nhiều khách hàng không vô tình ghi đè các thay đổi của nhau. API dữ liệu thực hiện việc này bằng cách thực hiện các thao tác cập nhật và xoá nếu ứng dụng chỉ định một ETag cũ cho mục nhập.

Có hai loại ETag: yếu và mạnh. Một ETag yếu luôn bắt đầu bằng W/, ví dụ: W/"D08FQn8-eil7ImA9WxZbFEw". ETag không đảm bảo sẽ thay đổi khi mục nhập thay đổi, do đó, HTTP cho phép chỉ sử dụng chúng để truy xuất có điều kiện. Thẻ Estrong mạnh xác định một phiên bản cụ thể của một mục cụ thể và có thể được sử dụng cả để truy xuất có điều kiện và trong quá trình cập nhật hoặc xoá nhằm tránh ghi đè thay đổi của các ứng dụng khác. Do sự khác biệt này, thư viện ứng dụng sẽ không cho phép bạn gửi ETag yếu với yêu cầu cập nhật hoặc xoá.

Bạn có thể tìm thấy thẻ điện tử ở hai vị trí trong phản hồi của máy chủ:

  • Trong tiêu đề HTTP ETag.
  • Trong nguồn cấp dữ liệu/mục nhập, dưới dạng thuộc tính gd:etag.

Nếu một dịch vụ hỗ trợ Phiên bản 2, thì mỗi đối tượng nguồn cấp dữ liệu và mục nhập sẽ có một phương thức getEtag() để truy xuất giá trị của ETag.

Ứng dụng JavaScript hỗ trợ hai phương thức để bao gồm ETag với một yêu cầu. Đầu tiên là đối tượng opt_params mới. Tất cả hàm get/update/insert trong Phiên bản 2 của thư viện ứng dụng đều có tham số opt_params mới. Đối tượng này dùng để chỉ định các tham số không bắt buộc khi tạo yêu cầu. Hiện tại, 'etag' là tham số không bắt buộc duy nhất được hỗ trợ (mặc dù các tham số khác có thể được giới thiệu trong tương lai). Ví dụ: bạn có thể thêm ETag vào một yêu cầu GET như sau:

var opt_params = {};
opt_params['etag'] = 'ETAG GOES HERE';
service.getFeed(uri, successHandler, errorHandler, opt_params);

Bạn cũng có thể thêm trực tiếp ETag vào một nguồn cấp dữ liệu hoặc đối tượng mục nhập bằng cách gọi phương thức setEtag() trên nguồn cấp dữ liệu/mục nhập.

Bạn có thể tìm hiểu thêm về ETag từ Tài liệu tham khảo về Giao thức GData.

Sử dụng ETag để Truy xuất dữ liệu

ETag có thể giúp giảm băng thông và thời gian thực thi khi truy xuất dữ liệu. Có thể có một ETag trong yêu cầu GET với If-None-Match header:

If-None-Match: ETAG GOES HERE

Nếu ETag khớp với phiên bản nguồn cấp dữ liệu hoặc mục nhập hiện tại, thì máy chủ sẽ phản hồi bằng phản hồi 304 NOT MODIFIED và phần nội dung trống. Nếu không, máy chủ sẽ phản hồi bằng phản hồi 200 OK và dữ liệu trong nguồn cấp dữ liệu hoặc mục nhập.

Bạn có thể sử dụng ETag trong ứng dụng JavaScript bằng cách bao gồm tham số 'etag' khi tạo yêu cầu:

var etag = feed.getEtag(); // Feed loaded from a previous request
var opt_params = {};
opt_params['etag'] = etag;
service.getFeed(feedUrl, successHandler, errorHandler, opt_params);

Truy xuất có điều kiện hoạt động với cả ETag mạnh và yếu. Nếu ETag là một kết quả phù hợp, trình xử lý lỗi sẽ được gọi với phản hồi 304:

function successHandler(feedRoot) {
  // 200 response
  // Update UI to display updates
}

function errorHandler(errorObj) {
  if (errorObj.cause.getStatus() == 304) {
    // 304 response, do nothing
  }
  // otherwise the response is some other error
}

Hãy xem mẫu Truy xuất có điều kiện bằng Blogger để xem ví dụ thực tế hơn về cách sử dụng ETag trong ứng dụng JavaScript. Mẫu này thăm dò ý kiến Blogger trong khoảng thời gian 5 giây để tìm bản cập nhật cho blog của bạn. Khi có thay đổi, mẫu sẽ cập nhật danh sách bài đăng.

Sử dụng ETag để cập nhật và xoá dữ liệu

Việc sử dụng ETag trên các yêu cầu cập nhật/xoá sẽ đảm bảo rằng nhiều ứng dụng không vô tình ghi đè các thay đổi của nhau. Trong trường hợp này, ETag được bao gồm với tiêu đề If-Match:

If-Match: ETAG GOES HERE

Nếu ETag trong yêu cầu khớp với ETag trên máy chủ, thì quá trình cập nhật/xoá thành công. Tuy nhiên, ETag không khớp cho biết mục đã thay đổi và cập nhật/xoá không thành công. Trong trường hợp này, ứng dụng nên yêu cầu một phiên bản dữ liệu mới rồi thử cập nhật/xoá lại.

Trong một số trường hợp, bạn có thể phải buộc thay đổi, bất kể mọi thay đổi khác đối với mục nhập. Bạn có thể thực hiện việc này bằng cách chuyển một * đến tiêu đề If-Match:

If-Match: *

Xin lưu ý rằng thao tác này sẽ ghi đè thay đổi do các ứng dụng khác thực hiện. Vì vậy, hãy sử dụng cẩn thận.

Bạn chỉ có thể cập nhật/xoá mục nhập có ETag mạnh. Việc chỉ định ETag yếu sẽ dẫn đến lỗi. Để tránh trường hợp này, ứng dụng JavaScript sẽ không đặt ETag yếu khi cập nhật và xoá yêu cầu.

ETag được sử dụng theo cách tương tự như truy xuất có điều kiện:

function updateData(entry, service) {
  var etag = entry.getEtag();
  var opt_params = {};
  opt_params['etag'] = etag; // Or use '*' to force an update.
  service.updateEntry(successHandler, errorHandler, opt_params);
}

function successHandler(response) {
  // Successful update
}

function errorHandler(errorObj) {
  // ERROR - Update failed. Could be due to an ETag mismatch, but check the
  // error message to make sure. An ETag error will be in the format:
  // Mismatch: etags = ["Qnc-fTVSLyp7ImA9WxJbFEsDRAw."], version = [1249675665358000]
}

Khi cập nhật, bạn có thể chỉ định ETag ở hai nơi:

  1. Trong chính mục nhập, sử dụng các phương thức getEtag()setEtag().
  2. Trong tiêu đề, hãy sử dụng đối tượng opt_params (như minh hoạ ở trên).

Mục nhập được tải từ yêu cầu GET trước đó đã được đặt trường ETag. Vì vậy, việc chỉ định cùng một ETag trong đối tượng opt_params là không cần thiết. Trong trường hợp ETag được chỉ định cả trong phần nội dung mục nhập và trong opt_params, ETag trong opt_params sẽ được ưu tiên. Điều này có thể gây nhầm lẫn một chút, vì vậy, nếu bạn gặp vấn đề với các bản cập nhật có điều kiện, hãy nhớ kiểm tra ETag trong cả mục nhập và đối tượng opt_params.

Để mọi thứ dễ dàng hơn, các lớp google.gdata.Entry cũng có phương thức updateEntry()deleteEntry() riêng. Nếu lớp nhập đã có ETag, bạn không phải thêm nó vào yêu cầu; thư viện ứng dụng sẽ tự động làm việc này cho bạn. Ví dụ:

// entry was loaded from a previous request.  No need to specify
// an ETag in opt_params here, it is added automatically.
entry.deleteEntry(successHandler, errorHandler);

Điều này giúp bạn có được lợi ích của ETag mà không phải lo lắng nếu cài đặt đúng cách. Tuy nhiên, nếu muốn buộc cập nhật bằng '*', bạn phải luôn bao gồm đối tượng opt_params bằng 'etag' = '*'.

Bạn có thể thấy bản cập nhật có điều kiện hoạt động trong phần Cập nhật có điều kiện trong Danh bạ. Trước tiên, mẫu sẽ tạo một Nhóm liên hệ thử nghiệm, nơi tất cả dữ liệu mà mẫu này sử dụng sẽ được tạo. Vui lòng xoá Nhóm liên hệ này khi bạn sử dụng xong mẫu. Sau đó, mẫu tải hai iframe với nội dung từ Nhóm liên hệ. Bạn có thể cập nhật trong một iframe và xem chúng ảnh hưởng đến cập nhật trong iframe khác như thế nào. Hãy truy cập mẫu để biết thêm chi tiết về cách sử dụng.

Mẫu

Tham chiếu

Để biết thông tin tham khảo về các lớp và phương thức do thư viện ứng dụng cung cấp, hãy xem tài liệu tham khảo API về thư viện ứng dụng JavaScript (ở định dạng JSdoc).

Trở lại đầu trang