Attribute的源码解析:
--注:这部分的源码阅读起来比较费劲,可能解析的还不太到位,后续会多读几遍增添新的解释,后面随时更新。
// 负责 attributes 的初始化
// attributes 是与实例相关的状态信息,可读可写,发生变化时,会自动触发相关事件
exports.initAttrs = function(config) {
// initAttrs 是在初始化时调用的,默认情况下实例上肯定没有 attrs,不存在覆盖问题
// 在Base的initialize方法里进行调用,因此不存在覆盖的问题
var attrs = this.attrs = {};
// Get all inherited attributes.
// 获取所有需要继承的属性,specialProps是一个数组,里面存的是属性名称
var specialProps = this.propsInAttrs || [];
// 该方法的注释见下面,用于将所有的特殊指定的属性格式化固定格式后扩展到attrs里面
mergeInheritedAttrs(attrs, this, specialProps);
// Merge user-specific attributes from config.
if (config) {
mergeUserValue(attrs, config);
}
// 对于有 setter 的属性,要用初始值 set 一下,以保证关联属性也一同初始化
setSetterAttrs(this, attrs, config);
// Convert `on/before/afterXxx` config to event handler.
// 转化`on/before/afterXxx`的配置转化为事件处理
parseEventsFromAttrs(this, attrs);
// 将 this.attrs 上的 special properties 放回 this 上
copySpecialProps(specialProps, this, attrs, true);
};
// Get the value of an attribute.
// 从Base实例属性attrs里取对应的key值,都是:
// {
// value:,
// getter:,
// setter:
//}格式,有getter的默认会执行getter方法
exports.get = function(key) {
var attr = this.attrs[key] || {};
var val = attr.value;
return attr.getter ? attr.getter.call(this, val, key) : val;
};
// Set a hash of model attributes on the object, firing `"change"` unless you choose to silence it.
// 在对象上set模型属性hash值的时候默认会触发“change”事件,你也可以选择不触发
exports.set = function(key, val, options) {
var attrs = {};
// set("key", val, options)格式
if (isString(key)) {
attrs[key] = val;
}
// set({ "key": val, "key2": val2 }, options)格式(此时只有两个参数或一个,options可选)
else {
attrs = key;
options = val;
}
// 给options赋默认值防报错
options || (options = {});
// 设置了silent则不会触发change事件
var silent = options.silent;
var override = options.override;
var now = this.attrs;
// 纪录被修改过的属性
var changed = this.__changedAttrs || (this.__changedAttrs = {});
for (key in attrs) {
// key必须是attrs的实例属性
if (!attrs.hasOwnProperty(key)) continue;
// 纪录被修改前的attr值
var attr = now[key] || (now[key] = {});
val = attrs[key]; // 对应要设置的val值
if (attr.readOnly) {// 只读的属性不允许被set
throw new Error('This attribute is readOnly: ' + key);
}
// invoke setter 调用setter
if (attr.setter) {
val = attr.setter.call(this, val, key);
}
// 获取设置前的 prev 值
var prev = this.get(key);
// 获取需要设置的 val 值
// 如果设置了 override 为 true,表示要强制覆盖,就不去 merge 了
// 都为对象时,做 merge 操作,以保留 prev 上没有覆盖的值
if (!override && isPlainObject(prev) && isPlainObject(val)) {
val = merge(merge({},prev), val);
}
// set finally
now[key].value = val;
// invoke change event
// 初始化时对 set 的调用,不触发任何事件
// 初始化的时候会调用setSetterAttrs方法,在该方法内会调用set方法,此时this.__initializingAttrs为true
if (!this.__initializingAttrs && !isEqual(prev, val)) {
if (silent) {
changed[key] = [val, prev];
} else {