@tangchao
2018-02-06T09:11:34.000000Z
字数 2360
阅读 1020
学习笔记
阅读 avalon 1.46 版本
关注点:
return技巧:
return,如果有,看他是否有副作用。如果没有,看方法是对调用的对象进行更改,还是对参数进行更改。纯函数,可以抽出来
vmsource 中普通属性生成 accessor,并将属性转化为访问器属性, get 和 set 为 accessor 对应的代码。 合并到 $vmodel。$vmodel$id, $model, $events, $watch, $unwatch, $fireget 收集生成相应的依赖<html> 开始扫描ms-controller,提取 vm, 组成一个 vmodels 列表attributes,遍历,筛出含有 ms 的属性binding,包含 element, type, value,将对应值存上去binding 增加 handler,根据 type 分配方法。bindings 存入到该 vm 上的 $event[keyName] 中。handler 刷新视图。第7步,是如何收集依赖注入的呢?
dependencyDetection,其中有一个空数组 outerFramesexecuteBindings:injectBinding: 开始执行 begin 将一个含 callback(参数 vmodel, accessor) 的对象 push 到 outerFrames 中collectDependency:callback,将会把这个 binding 添加到 $event[accessor._name] 中end,pop 这个 outerFramesvmvm 上某一个属性进行了赋值操作,则调用 set vm 和 vm.$model 的值$event[keyName],新的 value 和 item.el 为参数,执行其 handler$fire)该 vm 上 $watch 的方法$watch 的绑定与触发绑定:其实就是把回调函数 push 到 $event[keyName]。如果没有就手动创建一个。
触发:当 vm 改变的时候,会 $fire。而这个方法中,会遍历 $event[keyName],是函数,则执行它。
定义 vm 时,会执行 $reinitialize,将 accessor.digest (即执行一次 accessor) 注入依赖的 $event[dependencyKeyName]
扫描文档的 7.4 步,该计算属性访问器执行时 -> 调用 get -> 对依赖的简单属性进行求值 -> 执行 collectDependency -> 7.5 中 callback 接收的 accessor._name 就会是这个简单属性的
每一次被触发 accessor 时,如果值发生了改变,则会执行自己的 $event 来触发自己的 watch 的内容。
数据结构:
vm.$event.keyName 是数组本身操作触发
vm.keyName.proxies 上是各子项操作触发
更新:
长度不一样,先新增 add 或者删除 splice,再对剩下想同位置的元素进行 set:
把 proxies 对应子项作为 binding 去触发。
新增:
先在 proxies 生成 vm 上的数据,以及插入新的标签到 dom,
再对该 dom 进行 scan。
组件的使用:
注册一个组件 avalon.ui[widget]=function(){},其中内容主要有:
获取可配置的 options,组成 vm 或组件必须用的数据
定义 vm
有模板的,使用 avalon.parseHTML 生成元素,并插入到 DOM 中 element 相关的位置
$init 方法中 avalon.scan(element, [vm].concat(vmodels)),对新加入的元素一次扫描
源码原理:
执行组件的定义 avalon.ui[widget](elem, data, vmodels)
执行组件的 $init
通过解析表达式,生成 data.evaluator,中将执行 vm 上的函数,并把参数带上 vm 传入
data.args 为 vmodels
bindingExecutors.on 中:通过 avalon.bind 方法,给元素绑定一个回调,回调把 data.args 作为参数,执行 data.evaluator
avalon.bindingHandlers
avalon.bindingExecutors
avalon.vmodels
avalon.define
-> modelFactory
-> 遍历所有属性,每一个属性 makeSimpleAccessor 生成 accessor
-> accessor.updateValue 即 globalUpdateValue, accessor.notify 即 globalNotify
-> globalNotify 中 fireDependencies 及 EventBus.$fire.call
……> defineProperties
……> 添加: EventBus[i], $model, $events 等
avalon.scan
-> scanTag
-> scanAttr
-> 循环所有属性生成 binding 对象,然后添加到数组 bindings
-> executeBindings 循环 bindings
-> bindingHandlers[data.type](data, vmodels)
fireDependencies
-> fn.handler