准备

开始本教程之前,你需要做以下几点:

  • alexyoung / dailyjs-backbone-tutorial提交到了c1d5a2e7cc版本
  • 第二部分中的API key
  • 第二部分中的“Client ID”
  • 更新app/js/config.js成你自己的key(如果你检出了我的代码)

要检出源码,请运行以下命令(或用Git GUI工具):

git clone git@github.com:alexyoung/dailyjs-backbone-tutorial.git
cd dailyjs-backbone-tutorial
git reset --hard c1d5a2e7cc

Google’s Tasks API

回顾下我们要做的:我们教程是告诉大家怎样用Backbone.js开发一个SPA(单页应用),其中用到了Google客户端JavaScript认证和待办事项列表APIs

Google有两个APIs可以访问到待办事项列表:

我们页面引入Google’s JavaScript后,就可以通过一个全局的gapi对象去访问到APIs得不同的对象和方法.在最后一部分,我用了taskAPI执行了gapi.client.load函数

gapi.client.load('tasks', 'v1', function() { /* Loaded */ });

在这个app/js/gapi.js文件你可能早就已经看到了。剩下的挑战就是我们要通过gapi提供的Tasks和Tasklists APIs实现一个新的Backbone.sync方法。

Backbone.sync结构

Part 2我曾讲过Backbone.sync整体结构。在这部分我们将采用这种通用的模式来实现和Google’s APIs之间互相通信。

sync提供了三个参数,其中的第一个参数method是(create, update, delete, 和 read)之中一个,Google’s API相互对应下,具体代码如下:

Backbone.sync = function(method, model, options) {
  options || (options = {});

  switch (method) {
    case 'create':
    break;

    case 'update':
    break;

    case 'delete':
    break;

    case 'read':
    break;
  }
};

Google’s Tasks API 与Backbone的method对应关系:

Google Tasks API    Backbone.sync方法           解释
insert                create                     新建一个task
update                update                     更新已存在一个task
delete                delete                     删除一个task
list                read                     获取task列表

尽管Google’s API以Rails 3为基础的RESTful API设计看起来并不像Backbone.js的开放,但是还是很相近。

试用gapi发送请求

gapi发送请求方法如下: - 调用的gapi.client.tasks方法后返回request对象 - 请求用request.execute执行回调 - 请求成功以后(和ajax请求类似)返回一个response对象

具体的实现如下:

var requestContent = {}
  , request
  , gapiResource;

gapiResource = 'tasks';
requestContent['tasklist'] = tasklistId; // Assuming we have one
requestContent['resource'] = model.toJSON();

// 'insert' is for creating new tasks
request = gapi.client.tasks[gapiResource].insert(requestContent);

// Send the request to the API
request.execute(function(res) {
  // Handle the response
});

到这里很明显我们需要两个模型(models):TaskTaskList,同时需要相应的两个集合(collections):TasksTaskLists.

Backbone模型(models)和集合(collections)有个URLs - 用来发起API请求。同样, Google’s APIs也有个URLs:taskstaskLists.这样Backbone.sync就能切确的知道API资源对应的请求地址是什么了。

模型(models)

新建目录app/js/models并添加task.js:

define(function() {
  var Task = Backbone.Model.extend({
    url: 'tasks'
  });

  return Task;
});

同样还需要添加app/js/models/tasklist.js

define(function() {
  var TaskList = Backbone.Model.extend({
    url: 'tasklists'
  });

  return TaskList;
});

集合(collections)

新建目录app/js/collections并添加tasklists.js:

define(['models/tasklist'], function(TaskList) {
  var TaskLists = Backbone.Collection.extend({
    model: TaskList
  , url: 'tasklists'
  });

  return TaskLists;
});

这样我就可以使用TaskList集合来加载我们的任务列表。

发送API请求

编辑app/js/gapi.js在36后面添加:

app.views.auth.$el.hide();
$('#signed-in-container').show();
self.trigger('ready'); // This one

当认证成功之后会触发'ready'事件并且Tasks API也可以使用了。接下来,添加以下两行Backbone.sync,新增read条件:

case 'read':
  var request = gapi.client.tasks[model.url].list(options.data);
  Backbone.gapiRequest(request, method, model, options);
break;

这段代码发送了一个请求,紧接着会执行Backbone.gapiRequest函数并委托响应,下面是Backbone.gapiRequest的基本实现:

Backbone.gapiRequest = function(request, method, model, options) {
  var result;
  request.execute(function(res) {
    if (res.error) {
      if (options.error) options.error(res);
    } else if (options.success) {
      result = res.items;
      options.success(result, true, request);
    }
  });
};

request.execute是由Google提供的,执行函数后回触发Backbone’s API的successerror回调。

要让上面成功的执行,还需要修改app/js/app.js文件的define,添加TaskLists集合:

define([
  'gapi'
, 'views/app'
, 'views/auth'
, 'collections/tasklists'
],

function(ApiManager, AppView, AuthView, TaskLists) {

在这里加入connectGapi方法:

this.apiManager.on('ready', function() {
  self.collections.lists.fetch({ data: { userId: '@me' }, success: function(res) {
    _.each(res.models, function(model) {
      console.log(model.get('title'));
    });
  }});
});

在这段代码里,我们使用Underscore的each方法来遍历每个“模型”列表集合返回给Backbone.sync。运行服务器npm start,访问http://localhost:8080.如果浏览器支持console,你应该会看到任务列表已经被成功打印出来:

enter image description here

这样我就实现了Backbone.js的app与谷歌的API之间的通信。相同的还可以应用于Google其他的JavaScript API。

总结

教程中完整的代码可以在这里找到:alexyoung / dailyjs-backbone-tutorial, commit fcd653ec6