Arale Base源码分析(含Attribute)

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 {
       
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值