Part 5: 任務列表檢視

z.w發表於2015-01-14

準備

開始本教程之前,你需要了解以下幾點:

  • alexyoung / dailyjs-backbone-tutorial提交到了fcd653ec6版本
  • 第二部分中的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 fcd653ec6

線框

下面是我們需要構建的一些介面UI元素:

  • 兩欄佈局:左邊任務右邊列表
  • 每個列表都有編輯和刪除
  • 一些用於刪除專案和清除已完成專案的按鈕
  • 核取方塊(任務狀態控制)

具體的線框如下圖所示:

enter image description here

在這裡,我們將用一個無序列表來展示任務列表。

列表項

儘管比較簡單,實現一個任務選單導航還是涉及到了Backbone.js的一些元素:

  • HTML模板
  • Backbone檢視: ListMenuView, ListMenuItemView
  • Backbone集合: TaskLists

ListMenuView主要用於任務左側的選單導航,ListMenuItemView用於具體的任務列表專案,具體的都是用的ul包含li來實現的。

新建app/js/views/lists目錄來放任務列表相關的Backbone.View,新建app/js/templates/lists放對應的模板

選單列表容器檢視:ListMenuView

這個檢視寫在app/js/views/lists/menu.js:

define(['views/lists/menuitem'], function(ListMenuItemView) {
  var ListMenuView = Backbone.View.extend({
    el: '.left-nav',
    tagName: 'ul',
    className: 'nav nav-list lists-nav',

    events: {
    },

    initialize: function() {
      this.collection.on('add', this.render, this);
    },

    render: function() {
      // TODO
    }
  });

  return ListMenuView;
});

這個檔案依賴了views/lists/menuitem模組。繫結的.left-nav元素是在AppView的模板中的。導航選單本身是一個無序列表,而且還是用了一些相關的className來相關聯。

這個檢視還需要一個集合,來例項化檢視。例如:new ListMenuView({ collection: lists })就是通過lists集合來例項化的。

render方法就是這樣的:

render: function() {
  var $el = $(this.el)
    , self = this;

  this.collection.each(function(list) {
    var item, sidebarItem;
    item = new ListMenuItemView({ model: list });
    $el.append(item.render().el);
  });

  return this;
}

所有檢視的元素都包含在ListMenuItemView裡,通過遍歷模型集合來例項化這個檢視。

選單列表項檢視:ListMenuItemView

app/js/views/lists/menuitem.js和上面的檢視大體上類似,它區別是主要是通過使用檢視模板和Backbone來進行事件繫結:

define(['text!templates/lists/menuitem.html'], function(template) {
  var ListMenuItemView = Backbone.View.extend({
    tagName: 'li',
    className: 'list-menu-item',

    template: _.template(template),

    events: {
      'click': 'open'
    },

    initialize: function() {
      this.model.on('change', this.render, this);
      this.model.on('destroy', this.remove, this);
    },

    render: function() {
      var $el = $(this.el);
      $el.data('listId', this.model.get('id'));
      $el.html(this.template(this.model.toJSON()));
      return this;
    },

    open: function() {
      var self = this;
      return false;
    }
  });

  return ListMenuItemView;
});

app/js/templates/lists/menuitem.html模板:

<a href="#" class="list-title" data-list-id=""></a>

請注意,{}是用於插入值。這是由Underscore的模板系統提供的

在檢視中,click事件發生時會觸發open處理函式,模型也繫結了destroychange兩個事件來執行不能的處理

render裡可以用template方法來插入模板資料:

$el.html(this.template(this.model.toJSON()));

模型通過toJSONtitleid轉換成template需要的資料格式

呼叫ListMenuView

修改app/js/app.js檔案將ListMenuView作為依賴加入到define中:

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

function(ApiManager, AppView, AuthView, ListMenuView, TaskLists) {

在之前我們加了console.log在控制檯輸出列表的名稱,刪除這段替換成渲染ListMenuView檢視的程式碼:

connectGapi: function() {
  var self = this;
  this.apiManager = new ApiManager(this);
  this.apiManager.on('ready', function() {
    self.collections.lists.fetch({ data: { userId: '@me' }, success: function(res) {
      self.views.listMenu.render();
    }});
  });
}

回到App建構函式裡通過相關集合來例項化listMenu檢視:

var App = function() {
  this.views.app = new AppView();
  this.views.app.render();
  this.views.auth = new AuthView(this);
  this.views.auth.render();
  this.collections.lists = new TaskLists();
  this.views.listMenu = new ListMenuView({ collection: this.collections.lists });

  this.connectGapi();
};

執行

執行伺服器node server,訪問http://localhost:8080,你可以看到一個無序簡單的任務列表

總結

現在我們通過Google API拿到註冊使用者的任務列表並顯示到了也頁面中。雖然我們還沒有任何的樣式可能也不算什麼,但是你可以用Google APIs和相同的服務來做類似的應用,還是值得自我鼓勵下的。

這部分教程的程式碼:commit 82fe08e on GitHub

相關文章