第七章 列表视图
列表视图是我们使用的最为频繁的视图之一,本章就从前端的角度来介绍列表视图的组成和它所拥有的那些不为人知的特性。
从前面的知识,我们可以知道,在odoo中一种类型的视图至少需要拥有一个model,一个controller和一个render组成。
editable属性
取消"添加新一行"
List视图中默认会带着一个"添加新一行"的按钮, 有时候我们希望取消这个按钮, 这个时候我们可以在tree的属性中使用create属性来控制新增的显示与否
<tree create="0">
...
</tree>
同样的, 编辑也可以使用edit属性来控制
<tree edit="0">
...
</tree>
ListModel
我们先来看ListModel,我们知道ListView有一个重要的特点就是可以对数据进行分组显示。ListModel在初始化的时候,就初始化了一个groupbys的参数,这个参数用来标识视图需要依据哪些字段进行分组显示。
init: function (parent, params) {
this._super.apply(this, arguments);
this.groupbys = params.groupbys;
},
我们知道BaseModel获取数据使用的是get方法,ListModel同样也是使用get方法,但是它会根据当前是否是有需要分组显示的数据进行显示。
get: function () {
var result = this._super.apply(this, arguments);
var dp = result && this.localData[result.id];
if (dp && dp.groupData) {
result.groupData = this.get(dp.groupData);
}
return result;
}
在用户编辑了列表视图中的数据以后,列表视图需要将发生变化的数据回写到数据库中,调用的是saveRecords方法:
saveRecords: function (listDatapointId, referenceRecordId, recordIds, fieldName) {
var self = this;
var referenceRecord = this.localData[referenceRecordId];
var list = this.localData[listDatapointId];
// generate all record values to ensure that we'll write something
// (e.g. 2 records selected, edit a many2one in the first one, but
// reset same value, we still want to save this value on the other
// record)
var allChanges = this._generateChanges(referenceRecord, {changesOnly: false});
var changes = _.pick(allChanges, fieldName);
var records = recordIds.map(function (recordId) {
return self.localData[recordId];
});
var model = records[0].model;
var recordResIds = _.pluck(records, 'res_id');
var fieldNames = records[0].getFieldNames();
var context = records[0].getContext();
return this._rpc({
model: model,
method: 'write',
args: [recordResIds, changes],
context: context,
}).then(function () {
return self._rpc({
model: model,
method: 'read',
args: [recordResIds, fieldNames],
context: context,
});
}).then(function (results) {
results.forEach(function (data) {
var record = _.findWhere(records, {res_id: data.id});
record.data = _.extend({}, record.data, data);
record._changes = {};
record._isDirty = false;
self._parseServerData(fieldNames, record, record.data);
});
}).then(function () {
if (!list.groupedBy.length) {
return Promise.all([
self._fetchX2ManysBatched(list),
self._fetchReferencesBatched(list)
]);
} else {
return Promise.all([
self._fetchX2ManysSingleBatch(list),
self._fetchReferencesSingleBatch(list)
]);
}
});
}
从saveRecords的方法中,我们可以看到其内部使用了jsonrpc调用model的write方法将数据写入到数据库中,然后又调用了read方法将的数据取回并作了解析。