Part 9: 任務項
準備
開始本教程之前,你需要了解以下幾點:
- alexyoung / dailyjs-backbone-tutorial提交到了
0953c5d
版本 - 第二部分中的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 0953c5d
任務項CRUD
這部分將涵蓋以下內容:
- 新建單個任務項檢視
- 新建多個任務項的檢視
- 新增任務集合
- 利用Google’s API獲取任務
這裡需要處理一個父檢視和子檢視之間的關係,Backbone並沒有提供模型和檢視之間關係圖,這個例子中,我們理解的關係應該是任務項(tasks)屬於列表(lists),任務檢視(task views)屬於列表檢視(list views),雖然沒有這個關係沒有具體的呈現形式,但是在Backbone/Underscore已經又相應的程式碼去解決這個。
架子
開始之前,我們先新建好目錄:
$ mkdir app/js/views/tasks
$ mkdir app/js/templates/tasks
app/js/collections/tasks.js
中新增新集合:
define(['models/task'], function(Task) {
var Tasks = Backbone.Collection.extend({
model: Task,
url: 'tasks'
});
return Tasks;
});
Tasks
還沒有做任何事,現在我們需要通過Google’s API請求一個tasklist
來獲取任務項,在呼叫fetch
的時候還需要一個額外的引數:
collection.fetch({ data: { tasklist: this.model.get('id') }, // ...
我們處理獲取得到的TaskLists
,就和專案中已經存在的{ userId: '@me' }
資料類似。
我們還需要一個包含新建任務項表單和任務項列表容器的任務項檢視模板,被儲存到app/js/templates/index.js
:
<div class="span6">
<div id="add-task">
<form class="well row form-inline add-task">
<input type="text" class="pull-left" placeholder="Enter a new task's title and press return" name="title">
<button type="submit" class="pull-right btn"><i class="icon-plus"></i></button>
</form>
</div>
<ul id="task-list"></ul>
</div>
<div class="span6">
<div id="selected-task"></div>
<div class="alert" id="warning-no-task-selected">
<strong>Note:</strong> Select a task to edit or delete it.
</div>
</div>
我們使用了Bootstrap得佈局一些樣式類,在app/js/templates/tasks/task.html
的TaskView
檢視中,有title的span元素、notes的span元素和切換任務的狀態的checkbox核取方塊:
<input type="checkbox" data-task-id="" name="task_check_" class="check-task" value="t">
<span class="title "></span>
<span class="notes"></span>
檢視
TasksIndexView
通過Tasks
聚合載入任務項,用TaskView
檢視來渲染展示任務,具體的TasksIndexView
程式碼在app/js/views/tasks/index.js
中:
define(['text!templates/tasks/index.html', 'views/tasks/task', 'collections/tasks'], function(template, TaskView, Tasks) {
var TasksIndexView = Backbone.View.extend({
tagName: 'div',
className: 'row-fluid',
template: _.template(template),
events: {
'submit .add-task': 'addTask'
},
initialize: function() {
this.children = [];
},
addTask: function() {
},
render: function() {
this.$el.html(this.template());
var $el = this.$el.find('#task-list')
, self = this;
this.collection = new Tasks();
this.collection.fetch({ data: { tasklist: this.model.get('id') }, success: function() {
self.collection.each(function(task) {
var item = new TaskView({ model: task, parentView: self });
$el.append(item.render().el);
self.children.push(item);
});
}});
return this;
}
});
return TasksIndexView;
});
使用collection.fetch
獲取任務項,然後給每個任務項追加一個TaskView,這個TaskView
如下:
define(['text!templates/tasks/task.html'], function(template) {
var TaskView = Backbone.View.extend({
tagName: 'li',
className: 'controls well task row',
template: _.template(template),
events: {
'click': 'open'
},
initialize: function(options) {
this.parentView = options.parentView;
},
render: function(e) {
var $el = $(this.el);
$el.data('taskId', this.model.get('id'));
$el.html(this.template(this.model.toJSON()));
$el.find('.check-task').attr('checked', this.model.get('status') === 'completed');
return this;
},
open: function(e) {
if (this.parentView.activeTaskView) {
this.parentView.activeTaskView.close();
}
this.$el.addClass('active');
this.parentView.activeTaskView = this;
},
close: function(e) {
this.$el.removeClass('active');
}
});
return TaskView;
});
父檢視會判斷確定open
是否執行,是看是不是其他任務被點選和被關閉(刪除active
),實現這個又很多方式:可以遍歷檢視看看是不是關閉狀態(關閉狀態會通過$('selector').removeClass('active')
刪除相關的classactive
)或者在模型中通過觸發事件。我覺得應該在檢視中處理檢視相關的程式碼,模型和集合也應該是類似。
接下來我們需要把TasksIndexView
新增app/js/views/lists/menuitem.js
的define
中,修改open
方法,讓他去例項化一個TasksIndexView
檢視:
open: function() {
if (bTask.views.activeListMenuItem) {
bTask.views.activeListMenuItem.$el.removeClass('active');
}
bTask.views.activeListMenuItem = this;
this.$el.addClass('active');
// Render the tasks
if (bTask.views.tasksIndexView) {
bTask.views.tasksIndexView.remove();
}
bTask.views.tasksIndexView = new TasksIndexView({ collection: bTask.collections.tasks, model: this.model });
bTask.views.app.$el.find('#tasks-container').html(bTask.views.tasksIndexView.render().el);
return false;
}
在app/js/models/task.js
中新增一個預設的模型Task
:
define(function() {
var Task = Backbone.Model.extend({
url: 'tasks',
defaults: { title: '', notes: '' }
});
return Task;
});
我們給它了一個預設值{ title: '', notes: '' }
,新增預設值的原因—主要是避免我們通過Google Tasks獲取任務為空時出現錯誤
有了這些模板,檢視和修改,我們現在可以選擇列表,看到自己的任務,也可以選擇任務了
樣式
如圖,我們應用程式沒有太多的視覺元素, Bootstrap完全可以滿足需求—我們只去Bootstrap官網下載圖片和樣式檔案放到我們專案的app/img
和app/css
目錄下,然後在我們的頁面app/index.html
引入css/bootstrap.min.css
。
我們再給應用的任務皮膚加一些自定義樣式,這樣就看起來和Things介面差不多。
Backbone 0.9.10
我已經將Backbone升級到了0.9.10版本,app/js/gapi.js
中當呼叫options.success
時Backbone.sync
方法有點區別,修改下:
options.success(model, result, request);
總結
教程中完整的程式碼可以在這裡找到:alexyoung / dailyjs-backbone-tutorial, commit 0491ad
相關文章
- Part 10: 任務項新增、修改和切換狀態
- Part 6: 新建任務列表
- Part 7: 編輯任務列表
- Part 8: 刪除任務列表
- Part 5: 任務列表檢視
- 9項玩遊戲的極客必須攻破的任務遊戲
- 第八項任務——總結
- Flowable啟動流程例項和查詢任務以及完成任務
- 第三項任務——用例建模
- 第二項任務——專案需求分析
- 第四項任務——測試計劃
- 1.2.9. 任務9:資料庫效能優化資料庫優化
- netcore後臺任務注意事項NetCore
- 任務佇列,巨集任務與微任務佇列
- Study Plan For Algorithms - Part9Go
- 巨集任務和微任務
- 前端例項練習 - 任務清單 To do list前端
- 第五項任務—給出設計類圖
- 例項後臺執行訓練或任務
- JavaScript巨集任務和微任務JavaScript
- 任務
- MySQL定時任務與儲存過程例項MySql儲存過程
- Event Loop、 巨集任務和微任務OOP
- JavaScript的巨集任務與微任務JavaScript
- SpringBoot與非同步任務、定時任務、郵件任務Spring Boot非同步
- [MetalKit]15-Using-MetalKit-part-9使用MetalKit9
- [譯] part 9: golang 迴圈語句Golang
- 8086 彙編學習 Part 9
- 如何聰明地利用待辦事項 APP 完成任務APP
- Vue 2.0 入門系列(5)元件例項之任務列表Vue元件
- 微任務、巨集任務與Event-LoopOOP
- js中的巨集任務和微任務JS
- 任務系統之Jenkins子任務Jenkins
- macrotask 巨集任務 + microtask 微任務區別Mac
- 任務池
- 任務05
- crontab任務
- 任務四