| Đăng nhập qua LiketLy 

Hướng dẫn Viết ứng dụng (gadget) OpenSocial cơ bản PDF. In Email
(0 bình chọn, trung bình 0 trong 5 sao)
Những câu hỏi thường gặp (FAQs) - Developers - cho Nhà phát triển
Thứ bảy, 09 Tháng 7 2011 18:00

Bài viết này sẽ giới thiệu với các bạn về gadget và chuẩn Open Social. Dựa theo từng bước hướng dẫn trong bài, các bạn sẽ xây dựng được một ứng dụng xã hội đơn giản: tặng quà cho bạn bè của mình.

Cơ bản về gadget

Về cơ bản, các gadget là các file XML, đôi khi còn được gọi là các đặc tả gadget. Dưới đây là ví dụ về một gadget "Hello World" đơn giản minh họa cho các thành phần cơ bản của một đặc tả gadget:

<?xml version="1.0" encoding="UTF-8" ?>
 <Module>
   <ModulePrefs title="Hello World!">
     <Require feature="opensocial-0.8" />
   </ModulePrefs>
   <Content type="html">
     <![CDATA[
       Hello, world!
     ]]>
   </Content>
 </Module>

Trong ví dụ "Hello World" trên, bạn có thể thấy các thành phần điều khiển chức năng và giao diện của một gadget

  • <Module> chỉ ra rằng file XML này đặc tả một gadget.
  • <ModulePrefs> chứa thông tin về gadget cũng như tác giả của gadget.
  • <Require feature="opensocial-0.8" /> chỉ ra các chức năng mà gadget này cần sử dụng (ở đây là OpenSocial API phiên bản 0.8)
  • <Content type="html"> xác định nội dung của gadget là HTML. (là kiểu nội dung mặc định của gadget)
  • <![ CDATA[…]]> chứa nội dung của gadget, bao gồm các mã HTML, CSS, Javascript (hoặc là link đến các file CSS và Javascript). Nội dung của phần này tương tự như nội dung nằm bên trong thẻ <body> của một file HTML thông thường.

Viết ứng dụng đầu tiên

Chúng ta bắt đầu thảo luận chi tiết hơn về việc viết một gadget cụ thể. Bài viết này sẽ hướng dẫn bạn tạo ra một ứng dụng đơn giản cho phép người sử dụng tặng quà cho bạn bè của mình. Sau khi viết xong ứng dụng này, các bạn có thể:

  • Tặng quà cho bạn bè của mình.
  • Xem các quà đã tặng.
  • Xem quà được người khác tặng.

Thiết lập cơ bản

Trước hết, bạn hãy tạo một file XML và đặt tên là gifts.xml. Đặt tên cho ứng dụng của bạn là "Give Gifts" trong thuộc tính title của thẻ <ModulePrefs>, bạn có thể thêm các thông tin khác cho ứng dụng như tác giả, miêu tả ứng dụng... trong phần <ModulePrefs> này. Đây là file XML tôi đã tạo ra:

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Give Gifts - p0">
    <Require feature="opensocial-0.8"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
    ]]>
  </Content>
</Module>

Vậy là bạn đã tạo xong một gadget có tên là Give Gifts - p0. Rất đơn giản và dễ dàng, tuy nhiên gadget này chưa có chức năng cũng như giao diện. Ở các bước sau, chúng ta sẽ thêm dần các chức năng cho ứng dụng này.

Hiển thị danh sách bạn

Để có thể tặng quà cho bạn bè của mình, trước hết ứng dụng của bạn phải liệt kê được danh sách bạn bè của người đang sử dụng. Trong phần này, chúng ta sẽ tạo ra một gadget có thể hiển thị tất cả bạn bè của người dùng.

Trước hết, chúng ta viết hàm khởi tạo. Hàm này sẽ được gọi lúc gadget được chạy lần đầu tiên. Trong bước này hàm khởi tạo chỉ thực hiện đúng một thao tác, nhưng ở những phần sau hàm khởi tạo sẽ thực thi nhiều nhiệm vụ hơn.

gadgets.util.registerOnLoadHandler(init);
 
function init() {
  loadFriends();
}

Hàm loadFriends() sẽ lấy danh sách bạn của người dùng và hiển thị lên giao diện của gadget. Hàm này sẽ tạo ra một đối tượng data request mới, sau đó thực hiện request này để lấy về dữ liệu cần thiết, đó là thông tin về người dùng và danh sách bạn của người đó. Để thực hiện, chúng ta sẽ tạo ra một đối tượng IdSpec. Đối tượng IdSpec được sử dụng để xác định một hoặc nhiều người trong một nhóm. Sau đó đối tượng IdSpec này được gửi theo request đến server. Lưu ý rằng các request từ gadget đều là các request AJAX nên chúng ta cần chỉ ra tên hàm sẽ xử lý giá trị trả về của request. Hàm loadFriends() được viết như sau:

function loadFriends() {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');
 
  var viewerFriends = opensocial.newIdSpec({ "userId" : "VIEWER",
                                             "groupId" : "FRIENDS" });
  var opt_params = {};
  opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100;
  req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends');
 
  req.send(onLoadFriends);
}

Hàm xử lý dữ liệu trả về (callback function) onLoadFriends sẽ xử lý dữ liệu trả về từ server và hiển thị danh sách bạn bè của người dùng lên giao diện của gadget.

function onLoadFriends(data) {
  var viewer = data.get('viewer').getData();
  var viewerFriends = data.get('viewerFriends').getData();
 
  html = new Array();
  html.push('<ul>');
  viewerFriends.each(function(person) {
    html.push('<li>' + person.getDisplayName() + "</li>");
  });
  html.push('</ul>');
  document.getElementById('friends').innerHTML = html.join('');
}

Để hiển thị được danh sách này, chúng ta cần thêm một số thẻ div trên phần giao diện của gadget. Khi đó đặc tả gadget của chúng ta sẽ như sau:

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Give Gifts - p1">
    <Require feature="opensocial-0.8"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <script type="text/javascript">
        /* ... */
      </script>
      '''<div id='main'>
        Danh sách bạn:
        <div id='friends'></div>
      </div>
    ''']]>
  </Content>
</Module>

Tặng quà

Bây giờ chúng ta sẽ đi vào triển khai chức năng chính của gadget là tặng quà. Gadget sẽ cho phép người dùng tặng một món quà cho một người bạn của mình

Trước hết, bạn hãy sửa phần hiển thị của gadget để thể hiện chức năng tặng quà cho bạn bè: thêm danh sách quà và trước và nút Tặng quà vào sau danh sách bạn

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Give Gifts - p2">
    <Require feature="opensocial-0.8"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <script type="text/javascript">
        /* ... */
      </script>
      <div id='main'>'''
        <div id='give'>
          <form id='gift_form'>
            Tặng quà <span id='gifts'></span> cho <span id='friends'></span>. 
            <a href='javascript:void(0);' onclick='giveGift();'>Tặng quà!</a>
          </form>
        </div>'''
      </div>
    ]]>
  </Content>
</Module>

Tiếp theo chúng ta phải sửa lại hàm onLoadFriends() đã viết lúc trước để hiển thị danh sách bạn dưới dạng một combo box.

function onLoadFriends(data) {
  var viewer = data.get('viewer').getData();
  var viewerFriends = data.get('viewerFriends').getData();
 
  html = new Array();
  html.push('<select id="person">');
  viewerFriends.each(function(person) {
    if (person.getId()) {
      html.push('<option value="', person.getId(), '">',
                 person.getDisplayName(), '</option>');
    }
  });
  html.push('</select>');
  document.getElementById('friends').innerHTML = html.join('');
}

Sau đó, bạn cần thêm một combo box khác hiển thị danh sách các quà tặng cho người sử dụng chọn quà. Danh sách các món quà có thể được lưu trữ trong cơ sở dữ liệu và được lấy về lúc gadget được gọi lần đầu tiên, tuy nhiên để đơn giản, trong ví dụ này chúng ta định nghĩa sẵn danh sách một số món quà trong một mảng. Chúng ta cũng thêm một chức năng vào hàm khởi tạo để có thể hiện thị danh sách quà tặng ngay từ đầu.

var globalGiftList = ['Hoa', 'Dây chuyền', 'Nhẫn', 'Vòng tay'];
 
function makeOptionsMenu() {
  var html = new Array();
  html.push('<select id="giftlist">');
  for (var i = 0; i < globalGiftList.length; i++) {
    html.push('<option value="', i, '">', globalGiftList[i], '</option>');
  }
  html.push('</select>');
  document.getElementById('gifts').innerHTML = html.join('');
}
 
function init() {
  loadFriends();
  makeOptionsMenu();
}

Cuối cùng, chúng ta sẽ thực hiện chức năng tặng quà giveGift. Hàm giveGift sẽ được gọi mỗi khi người sử dụng click vào nút Tặng quà trên giao diện. Hàm này sẽ lấy thông tin về món quà được tặng, người được tặng quà và lưu trữ lại vào cơ sở dữ liệu.

var globalGivenGifts = {};
 
function giveGift() {
  var gifted = document.getElementById('giftlist').value;
  var friend = document.getElementById('person').value;
 
  givenGifts[friend] = gifted;
  var json = gadgets.json.stringify(givenGifts);
 
  var req = opensocial.newDataRequest();
  req.add(req.newUpdatePersonAppDataRequest("VIEWER", 'gifts', json));
  req.send();
}

Danh sách quà được tặng

Đến đây, gadget của chúng ta đã có chức năng tặng quà. Tuy vậy, người tặng  không biết được rằng món quà mình gửi đi đã thành công hay chưa. Do đó, để ứng dụng thân thiện với người dùng hơn, chúng ta sẽ thêm chức năng hiển thị danh sách quà đã tặng vào trong gadget.

Việc này có thể thực hiện đơn giản bằng cách sử dụng đối tượng globalGivenGifts chúng ta đã khai báo ở trên, với cách tiếp cận này chúng ta chỉ có thể hiển thị danh sách quà đã tặng trong một lần vào ứng dụng, do dữ liệu của chúng ta không được liên kết đến một cơ sở dữ liệu nào. Bên cạnh đó, bạn cũng không thể biết được thao tác tặng quà mình vừa thực hiện có thành công hay không. Ở đây, chúng ta sẽ liên kết đến cơ sở dữ liệu của container, lấy ra danh sách quà đã tặng và lưu trữ vào đối tượng globalGivenGifts.

Bạn cần phải cập nhật danh sách quà đã tặng trong 2 trường hợp. Trường hợp thứ nhất là khi gadget được load, để hiển thị quà bạn đã tặng trước đây. Trường hợp thứ hai là khi bạn thực hiện thao tác tặng quà, để chắc chắn rằng quà của bạn đã được tặng.

Trước hết, bạn hãy thêm 2 request vào đối tượng dataRequest trong hàm giveGift để lấy thông tin của người sử dụng và danh sách bạn bè, sau đó chúng ta thêm một hàm callback để xử lý dữ liệu trả về của thao tác sendGift.

function giveGift() {
  var gifted = document.getElementById('giftlist').value;
  var friend = document.getElementById('person').value;
 
  givenGifts[friend] = gifted;
  var json = gadgets.json.stringify(givenGifts);
 
  var req = opensocial.newDataRequest();
  req.add(req.newUpdatePersonAppDataRequest("VIEWER", 'gifts', json));
  '''req.add(req.newFetchPersonRequest("VIEWER"), 'viewer');
 
  var viewerFriends = opensocial.newIdSpec({ "userId" : "VIEWER",
                                             "groupId" : "FRIENDS" });
  var opt_params = {};
  opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100;
  req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends');
 
  var viewer = opensocial.newIdSpec({ "userId" : "VIEWER" });
  req.add(req.newFetchPersonAppDataRequest(viewer, 'gifts'), 'data');'''
  req.send(onLoadFriends);
}

Ở đây, chúng ta tận dụng hàm onLoadFriends đã viết để xử lý dữ liệu trả về trong  cả 2 trường hợp, do đó hàm loadFriends và onLoadFriends cần phải sửa lại một chút như sau:

function loadFriends() {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest("VIEWER"), 'viewer');
 
  var viewerFriends = opensocial.newIdSpec({ "userId" : "VIEWER",
                                             "groupId" : "FRIENDS" });
  var opt_params = {};
  opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100;
  req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends');
 
  var viewer = opensocial.newIdSpec({ "userId" : "VIEWER" });
  '''req.add(req.newFetchPersonAppDataRequest(viewer, 'gifts', opt_params),
             'data');'''
  req.send(onLoadFriends);
}

Hàm onLoadFriends sẽ gọi một hàm khác để xử lý dữ liệu về các món quà đã tặng

function onLoadFriends(data) {
  var viewer = data.get('viewer').getData();
  var viewerFriends = data.get('viewerFriends').getData();
  var giftData = data.get('data').getData();
 
  html = new Array();
  html.push('<select id="person">');
  viewerFriends.each(function(person) {
    if (person.getId()) {
      html.push('<option value="', person.getId(), '">',
                 person.getDisplayName(), '</option>');
    }
  });
  html.push('</select>');
  document.getElementById('friends').innerHTML = html.join('');
 
  '''updateGiftList(viewer, giftData, viewerFriends);'''
}

Tiếp theo, chúng ta  sẽ viết hàm updateGiftList để cập nhật và hiển thị kết quả trả về. Trong trường hợp dữ liệu trả về có lỗi, đối tượng globalGivenGifts sẽ bị xóa trắng.

function updateGiftList(viewer, data, friends) {
  var json = null;
  if (data[viewer.getId()]) {
    json = data[viewer.getId()]['gifts'];
  }
 
  if (!json) {
    globalGivenGifts = {};
  }
  try {
    globalGivenGifts = gadgets.json.parse(gadgets.util.unescapeString(json));
  } catch (e) {
    globalGivenGifts = {};
  }
 
  var html = new Array();
  html.push('Các món quà đã tặng:');
  html.push('<ul>');
  for (i in globalGivenGifts) {
    if (i.hasOwnProperty) {
      html.push('<li>', friends.getById(i).getDisplayName(), ' nhận ',
                 globalGiftList[globalGivenGifts[i]], '</li>');
    }
  }
  html.push('</ul>');
  document.getElementById('given').innerHTML = html.join('');
}

Cuối cùng, bạn cần chỉ ra một vị trí trên giao diện của gadget để hiển thị danh sách quà đã tặng:

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Give gifts - p3">
    <Require feature="opensocial-0.8"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <script type="text/javascript">
        /* ... */
      </script>
      <div id='main'>
        <div id='give'>
          <form id='gift_form'>
            Tặng quà<span id='gifts'></span> cho <span id='friends'></span>.
            <a href='javascript:void(0);' onclick='giveGift();'>Tặng quà!</a>
          </form>
        </div>
        '''<div id='given'></div>'''
      </div>
    ]]>
  </Content>
</Module>

Hiển thị các món quà được tặng

Gadget của chúng ta đã có chức năng tặng quà cho bạn bè, tuy nhiên về phía người nhận không thể nào biết được họ đã được ai tặng quà gì. Trong phần này, chúng ta tiếp tục thêm chức năng hiển thị quà được tặng vào gadget.

Thêm chức năng hiển thị quà được tặng không phức tạp, nhưng đòi hỏi người lập trình phải sử dụng các truy vấn vào cơ sở dữ liệu một cách hiệu quả. Hiện tại, ứng dụng chỉ có thể lưu trữ dữ liệu của người dùng của gadget vào cơ sở dữ liệu. Khi một người bạn (người A) của người tặng quà (người B) vào gadget, gadget sẽ duyệt trong cơ sở dữ liệu những người bạn của người A để xem những người bạn nào của A đã tặng quà cho A. Bạn có thể tự mình lưu trữ những dữ liệu này trên server của bạn, hoặc có thể đọc dữ liệu của ứng dụng được lưu trữ trên container.

Để bắt đầu, chúng ta hãy tạo ra một vị trí hiển thị quà đã nhận trên giao diện gadget

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Give gifts - p4">
    <Require feature="opensocial-0.8"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
      <script type="text/javascript">
        /* ... */
      </script>
      <div id='main'>
        <div id='give'>
          <form id='gift_form'>
            Tặng quà<span id='gifts'></span> cho <span id='friends'></span>.
            <a href="javascript:void(0);" onclick='giveGift();'>Tặng quà!</a>
          </form>
        </div>
        <div id='given'></div>
        '''<div id='received'></div>'''
      </div>
    ]]>
  </Content>
</Module>

Tiếp theo, bạn phải sửa lại các hàm truy cập cơ sở dữ liệu. Đầu tiên, cập nhật hàm loadFriends để lấy về danh sách quà đã tặng

function loadFriends() {
  var req = opensocial.newDataRequest();
  req.add(req.newFetchPersonRequest("VIEWER"), 'viewer');
 
  var viewerFriends = opensocial.newIdSpec({ "userId" : "VIEWER",
                                             "groupId" : "FRIENDS" });
  var opt_params = {};
  opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100;
  req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends');
 
  var viewer = opensocial.newIdSpec({ "userId" : "VIEWER" });
  req.add(req.newFetchPersonAppDataRequest(viewer, 'gifts'), 'data');
 
  '''req.add(req.newFetchPersonAppDataRequest(viewerFriends, 'gifts', opt_params),
             'viewerFriendData');'''
  req.send(onLoadFriends);
}

Hàm giveGift cũng được cập nhật giống như trên: (Chú ý rằng cả 2 hàm này đều sử dụng chung một hàm callback nên dữ liệu lấy về phải nhất quán với nhau)

function giveGift() {
  var gifted = document.getElementById('giftlist').value;
  var friend = document.getElementById('person').value;
 
  givenGifts[friend] = nut;
  var json = gadgets.json.stringify(givenGifts);
 
  var req = opensocial.newDataRequest();
  req.add(req.newUpdatePersonAppDataRequest("VIEWER", 'gifts', json));
  req.add(req.newFetchPersonRequest("VIEWER"), 'viewer');
 
  var viewerFriends = opensocial.newIdSpec({ "userId" : "VIEWER",
                                             "groupId" : "FRIENDS" });
  var opt_params = {};
  opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] = 100;
  req.add(req.newFetchPeopleRequest(viewerFriends, opt_params), 'viewerFriends');
 
  var viewer = opensocial.newIdSpec({ "userId" : "VIEWER" });
  req.add(req.newFetchPersonAppDataRequest(viewer, 'gifts'), 'data');
 
  '''req.add(req.newFetchPersonAppDataRequest(viewerFriends, 'gifts', opt_params),
             'viewerFriendData');'''
  req.send(onLoadFriends);
}

Hàm callback onLoadFriends cũng cần cập nhật để trả về dữ liệu bạn bè của người sử dụng, truyền dữ liệu đó cho hàm updateReceivedList để lấy danh sách quà đã được tặng.

function onLoadFriends(data) {
  var viewer = data.get('viewer').getData();
  var viewerFriends = data.get('viewerFriends').getData();
  var giftData = data.get('data').getData();
  '''var viewerFriendData = data.get('viewerFriendData').getData();'''
 
  html = new Array();
  html.push('<select id="person">');
  viewerFriends.each(function(person) {
    if (person.getId()) {
      html.push('<option value="', person.getId(), '">',
                person.getDisplayName(), '</option>');
    }
  });
  html.push('</select>');
  document.getElementById('friends').innerHTML = html.join('');
 
  updateGiftList(viewer, giftData, viewerFriends);
  '''updateReceivedList(viewer, viewerFriendData, viewerFriends);'''
}

Cuối cùng chúng ta viết hàm updateReceivedList tương tự như hàm updateGiftList, nhưng thay vì duyệt qua danh sách các quà bạn đã tặng, hàm này duyệt qua danh sách quà mà mỗi người bạn của người dùng đã tặng, và hiển thị dữ liệu nếu người nhận là người dùng.

function updateReceivedList(viewer, data, friends) {
  var viewerId = viewer.getId();
 
  var html = new Array();
  html.push('Bạn đã nhận:<ul>');
  friends.each(function(person) {
    if (data[person.getId()]) {
      var json = data[person.getId()]['gifts'];
 
      var gifts = {}
      if (!json) {
        gifts = {};
      }
      try {
        gifts = gadgets.json.parse(gadgets.util.unescapeString(json));
      } catch (e) {
        gifts = {};
      }
 
      for (i in gifts) {
        if (i.hasOwnProperty && i == viewerId) {
          html.push('<li>', globalGiftList[gifts[i]], ' từ ',
                    person.getDisplayName(), '</li>');
        }
      }
    }
  });
  html.push('</ul>');
  document.getElementById('received').innerHTML = html.join('');
}

Lưu ý: bạn hoàn toản có thể dặt các mã js, css... vào các file đặt ở server của bạn, tiện cho việc có thay đổi code... sau này, ngay cả khi tiện ích đã được cài tại ketnooi!

Nguồn http://developer.tamtay.vn/tutorial