今天來完成剩下的兩個事件 新增
和 編輯
首先先來處理 新增
的部分,先調整模板
主要處理的部分有
+
按鈕在最下方edit
狀態來記錄id
為空時,代表為新增<t t-name="todoList">
<table>
<tbody>
<t t-if="items.length">
<tr t-foreach="items" t-as="item">
<td>
<input type="checkbox"
class="finished"
t-att-checked="item.finished ? 'checked' : undefined"
t-att-data-index="item_index"/>
</td>
<td>
<div t-if="!item.edit" t-esc="item.name"
t-att-data-index="item_index" class="todo-name"/>
<input t-else=""
type="text" class="todo-name-input"
t-att-value="item.name"/>
</td>
<td>
<i t-attf-class="fa fa-{{ item.edit ? 'check' : 'times' }}"
t-att-data-index="item_index"/>
</td>
</tr>
</t>
<tr t-else="">
<td colspan="3">
<span class="alert alert-success">無任何的待辦事項</span>
</td>
</tr>
<tr>
<td colspan="3" class="pt-3">
<button type="button" class="btn btn-info w-100 text-center btn-new-todo">
<i class="fa fa-plus"/>
</button>
</td>
</tr>
</tbody>
</table>
</t>
接著調整 JS 的部分,增加兩個事件
'click .btn-new-todo': '_newItem',
'click i.fa-check': '_saveItem',
加入對應的函式
_newItem: function () {
let alreadyHaveNewOne = !!this.todoList.filter(item => !item.id).length;
if (alreadyHaveNewOne) {
return true;
}
this.todoList.push({id: null, name: '', finished: false, edit: true});
this.renderElement();
this.el.querySelector('.todo-name-input').focus();
},
_saveItem: function (ev) {
const self = this;
let target = ev.currentTarget,
data_index = target.dataset.index;
if (!data_index) {
return true;
}
let index = parseInt(data_index);
let data = this.todoList.at(index);
if (!data) {
return true;
}
Object.assign(data, {
name: this.el.querySelector(`input.todo-name-input`).value,
finished: this.el.querySelector(`input[type='checkbox'][data-index="${index}"]`).checked,
})
this._rpc({
model: 'todo.list',
method: 'create',
args: [{
name: data.name,
finished: data.finished,
}]
}).then(result => {
if (result) {
data.id = result;
data.edit = false;
self.renderElement();
}
});
},
新增
就完成了,是不是很簡單呢
接下來 編輯
的部份,因為在新增的時候就有先把模板先改好了,就是 [item.name](http://item.name)
的部分
<div t-if="!item.edit" t-esc="item.name"
t-att-data-index="item_index" class="todo-name"/>
所以接下來要調整一下 JS
一樣增加對應的事件
'click .todo-name': '_editItem',
增加對應的函式
_editItem: function (ev) {
let target = ev.currentTarget,
data_index = target.dataset.index;
if (!data_index) {
return true;
}
let index = parseInt(data_index);
let data = this.todoList.at(index);
if (!data) {
return true;
}
if (!data.edit) {
this.todoList.forEach(item => {
if (item.edit) {
item.edit = false;
}
});
data.edit = true;
this.renderElement();
this.el.querySelector('.todo-name-input').focus();
}
},
完成後重新整理網頁測試一下
咦? 編輯存檔後還是新增耶
是的,所以要調整一下 _saveItem()
,要增加判斷 id
是否為空,為空就是新增,反之則更新
_saveItem: function (ev) {
const self = this;
let target = ev.currentTarget,
data_index = target.dataset.index;
if (!data_index) {
return true;
}
let index = parseInt(data_index);
let data = this.todoList.at(index);
if (!data) {
return true;
}
let updateData = {
name: this.el.querySelector(`input.todo-name-input`).value,
finished: this.el.querySelector(`input[type='checkbox'][data-index="${index}"]`).checked,
};
Object.assign(data, updateData);
if (data.id) {
this._rpc({
model: 'todo.list',
method: 'write',
args: [[data.id], updateData]
}).then(result => {
if (result) {
data.edit = false;
self.renderElement();
}
});
} else {
this._rpc({
model: 'todo.list',
method: 'create',
args: [updateData]
}).then(result => {
if (result) {
data.id = result;
data.edit = false;
self.renderElement();
}
});
}
},
再次重新整理網頁測試後就正常了
當然我寫的程式有很多地方可以更精簡,就讓有興趣各位自行拆分職責了
最後有個小作業, _toggleFinish()
有一個很明顯的 BUG,
各位可以找一下在哪邊
Hint: 當資料為新增時,點完成會發生什麼事呢?