This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

优化vm定义,增加双下划线开头的属性为非监控属性的设定; :repeat指令更名为:for, 同时修复对象遍历选项改变后视图不同步的bug

old
宇天 2018-07-31 22:16:54 +08:00
parent a33cc30995
commit 35d4b39c7a
9 changed files with 293 additions and 141 deletions

View File

@ -1554,7 +1554,7 @@ const _Anot = (function() {
} }
//一些不需要被监听的属性 //一些不需要被监听的属性
var $$skipArray = oneObject( var kernelProps = oneObject(
'$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors' '$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors'
) )
@ -1567,6 +1567,11 @@ const _Anot = (function() {
return observeObject(source, options) return observeObject(source, options)
} }
function isSkip(k) {
return
k.charAt(0) === '$' || k.slice(0, 2) === '__' || kernelProps[k]
}
//监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现 //监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现
//监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴 //监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴
// 通过比较前后代理VM顺序实现 // 通过比较前后代理VM顺序实现
@ -1591,7 +1596,7 @@ const _Anot = (function() {
var hasOwn = {} var hasOwn = {}
var skip = [] var skip = []
var simple = [] var simple = []
var $skipArray = {} var userSkip = {}
// 提取 source中的配置项, 并删除相应字段 // 提取 source中的配置项, 并删除相应字段
var state = source.state var state = source.state
var computed = source.computed var computed = source.computed
@ -1607,7 +1612,7 @@ const _Anot = (function() {
delete source.watch delete source.watch
if (source.skip) { if (source.skip) {
$skipArray = oneObject(source.skip) userSkip = oneObject(source.skip)
delete source.skip delete source.skip
} }
@ -1620,14 +1625,13 @@ const _Anot = (function() {
} }
for (name in state) { for (name in state) {
var value = state[name] var value = state[name]
if (!$$skipArray[name]) { if (!kernelProps[name]) {
hasOwn[name] = true hasOwn[name] = true
} }
if ( if (
typeof value === 'function' || typeof value === 'function' ||
(value && value.nodeName && value.nodeType > 0) || (value && value.nodeName && value.nodeType > 0) ||
(!force[name] && (!force[name] && (isSkip(name) || userSkip[name]))
(name.charAt(0) === '$' || $$skipArray[name] || $skipArray[name]))
) { ) {
skip.push(name) skip.push(name)
} else if (isComputed(value)) { } else if (isComputed(value)) {
@ -1954,7 +1958,7 @@ const _Anot = (function() {
} }
/********************************************************************* /*********************************************************************
* 监控数组:repeat配合使用 * * 监控数组:for配合使用 *
**********************************************************************/ **********************************************************************/
var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice'] var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice']
@ -3386,7 +3390,7 @@ const _Anot = (function() {
for (var i = 0, attr; (attr = attributes[i++]); ) { for (var i = 0, attr; (attr = attributes[i++]); ) {
var name = attr.name var name = attr.name
if (uniq[name]) { if (uniq[name]) {
//IE8下:repeat,:with BUG //IE8下:for BUG
continue continue
} }
uniq[name] = 1 uniq[name] = 1
@ -3465,7 +3469,7 @@ const _Anot = (function() {
} }
} }
var rnoscanAttrBinding = /^if|widget|repeat$/ var rnoscanAttrBinding = /^if|for$/
var rnoscanNodeBinding = /^html|include$/ var rnoscanNodeBinding = /^html|include$/
function scanNodeList(elem, vmodels) { function scanNodeList(elem, vmodels) {
@ -3531,7 +3535,7 @@ const _Anot = (function() {
} }
function scanTag(elem, vmodels) { function scanTag(elem, vmodels) {
//扫描顺序 skip(0) --> anot(1) --> :if(10) --> :repeat(90) //扫描顺序 skip(0) --> anot(1) --> :if(10) --> :for(90)
//--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后 //--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后
var skip = elem.getAttribute('skip') var skip = elem.getAttribute('skip')
var node = elem.getAttributeNode('anot') var node = elem.getAttributeNode('anot')
@ -5555,7 +5559,7 @@ const _Anot = (function() {
} }
}) })
Anot.directive('repeat', { Anot.directive('for', {
priority: 90, priority: 90,
init: function(binding) { init: function(binding) {
var type = binding.type var type = binding.type
@ -5564,9 +5568,14 @@ const _Anot = (function() {
var elem = binding.element var elem = binding.element
if (elem.nodeType === 1) { if (elem.nodeType === 1) {
var vars = binding.expr.split(' in ')
binding.expr = vars.pop()
if (vars.length) {
vars = vars.pop().split(/\s+/)
}
binding.vars = vars
elem.removeAttribute(binding.name) elem.removeAttribute(binding.name)
effectBinding(elem, binding) effectBinding(elem, binding)
binding.param = binding.param || 'el'
var rendered = getBindingCallback( var rendered = getBindingCallback(
elem, elem,
'data-rendered', 'data-rendered',
@ -5600,12 +5609,28 @@ const _Anot = (function() {
var binding = this var binding = this
var xtype = this.xtype var xtype = this.xtype
if (xtype === 'array') {
if (!this.vars.length) {
this.vars.push('$index', 'el')
} else if (this.vars.length === 1) {
this.vars.unshift('$index')
}
this.param = this.vars[1]
} else {
this.param = '__el__'
if (!this.vars.length) {
this.vars.push('$key', '$val')
} else if (this.vars.length === 1) {
this.vars.push('$val')
}
}
this.enterCount += 1 this.enterCount += 1
var init = !oldValue var init = !oldValue
if (init) { if (init) {
binding.$outer = {} binding.$outer = {}
var check0 = '$key' var check0 = this.vars[0]
var check1 = '$val' var check1 = this.vars[1]
if (xtype === 'array') { if (xtype === 'array') {
check0 = '$first' check0 = '$first'
check1 = '$last' check1 = '$last'
@ -5670,9 +5695,12 @@ const _Anot = (function() {
} }
} else { } else {
action = 'append' action = 'append'
proxy.$key = keyOrId proxy[check0] = keyOrId
proxy.$val = value[keyOrId] //key proxy[check1] = value[keyOrId] //key
proxy[param] = { $key: proxy.$key, $val: proxy.$val } var tmp = {}
tmp[check0] = proxy[check0]
tmp[check1] = proxy[check1]
proxy[param] = tmp
} }
this.cache[keyOrId] = proxy this.cache[keyOrId] = proxy
var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false)) var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false))
@ -5702,8 +5730,9 @@ const _Anot = (function() {
if (xtype === 'array') { if (xtype === 'array') {
proxy.$first = i === 0 proxy.$first = i === 0
proxy.$last = i === length - 1 proxy.$last = i === length - 1
proxy[this.vars[0]] = proxy.$index
} else { } else {
proxy.$val = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况 proxy[check1] = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况
} }
proxies.push(proxy) proxies.push(proxy)
} }
@ -5777,7 +5806,7 @@ const _Anot = (function() {
} }
} }
//repeat --> duplex // :for --> duplex
;(function(args) { ;(function(args) {
_parent.args = args _parent.args = args
if (_parent.msRendered) { if (_parent.msRendered) {
@ -5890,13 +5919,16 @@ const _Anot = (function() {
binding.$repeat.removeAt(proxy.$index) binding.$repeat.removeAt(proxy.$index)
} }
var param = binding.param var param = binding.param
proxy.$watch(param, function(a) { proxy.$watch(param, function(val) {
var index = proxy.$index var index = proxy.$index
binding.$repeat[index] = a binding.$repeat[index] = val
}) })
} else { } else {
proxy.$watch('$val', function fn(a) { var __k__ = binding.vars[0]
binding.$repeat[proxy.$key] = a var __v__ = binding.vars[1]
proxy.$up.$watch(binding.expr + '.' + proxy[__k__], function(val) {
proxy[binding.param][__v__] = val
proxy[__v__] = val
}) })
} }
} }
@ -5914,12 +5946,14 @@ const _Anot = (function() {
} }
} }
if (!proxy) { if (!proxy) {
proxy = eachProxyFactory(itemName) proxy = eachProxyFactory(data)
} }
return proxy return proxy
} }
function eachProxyFactory(itemName) { function eachProxyFactory(data) {
var itemName = data.param || 'el'
var __k__ = data.vars[0]
var source = { var source = {
$outer: {}, $outer: {},
$index: 0, $index: 0,
@ -5930,12 +5964,14 @@ const _Anot = (function() {
$last: false, $last: false,
$remove: Anot.noop $remove: Anot.noop
} }
source[__k__] = 0
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$last: 1, $last: 1,
$first: 1, $first: 1,
$index: 1 $index: 1
} }
force[__k__] = 1
force[itemName] = 1 force[itemName] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
@ -5950,26 +5986,28 @@ const _Anot = (function() {
var withProxyPool = [] var withProxyPool = []
function withProxyAgent(data) { function withProxyAgent(data) {
var itemName = data.param || 'el' return withProxyPool.pop() || withProxyFactory(data)
return withProxyPool.pop() || withProxyFactory(itemName)
} }
function withProxyFactory(itemName) { function withProxyFactory(data) {
var itemName = data.param || '__el__'
var __k__ = data.vars[0]
var __v__ = data.vars[1]
var source = { var source = {
$key: '',
$val: NaN,
$index: 0, $index: 0,
$oldIndex: 0, $oldIndex: 0,
$outer: {}, $outer: {},
$anchor: null $anchor: null
} }
source[__k__] = ''
source[__v__] = NaN
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$key: 1, __el__: 1,
$val: 1,
$index: 1 $index: 1
} }
force[itemName] = 1 force[__k__] = 1
force[__v__] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
{ {

View File

@ -1569,7 +1569,7 @@
} }
//一些不需要被监听的属性 //一些不需要被监听的属性
var $$skipArray = oneObject( var kernelProps = oneObject(
'$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors' '$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors'
) )
@ -1582,6 +1582,11 @@
return observeObject(source, options) return observeObject(source, options)
} }
function isSkip(k) {
return
k.charAt(0) === '$' || k.slice(0, 2) === '__' || kernelProps[k]
}
//监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现 //监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现
//监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴 //监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴
// 通过比较前后代理VM顺序实现 // 通过比较前后代理VM顺序实现
@ -1606,7 +1611,7 @@
var hasOwn = {} var hasOwn = {}
var skip = [] var skip = []
var simple = [] var simple = []
var $skipArray = {} var userSkip = {}
// 提取 source中的配置项, 并删除相应字段 // 提取 source中的配置项, 并删除相应字段
var state = source.state var state = source.state
var computed = source.computed var computed = source.computed
@ -1622,7 +1627,7 @@
delete source.watch delete source.watch
if (source.skip) { if (source.skip) {
$skipArray = oneObject(source.skip) userSkip = oneObject(source.skip)
delete source.skip delete source.skip
} }
@ -1635,14 +1640,13 @@
} }
for (name in state) { for (name in state) {
var value = state[name] var value = state[name]
if (!$$skipArray[name]) { if (!kernelProps[name]) {
hasOwn[name] = true hasOwn[name] = true
} }
if ( if (
typeof value === 'function' || typeof value === 'function' ||
(value && value.nodeName && value.nodeType > 0) || (value && value.nodeName && value.nodeType > 0) ||
(!force[name] && (!force[name] && (isSkip(name) || userSkip[name]))
(name.charAt(0) === '$' || $$skipArray[name] || $skipArray[name]))
) { ) {
skip.push(name) skip.push(name)
} else if (isComputed(value)) { } else if (isComputed(value)) {
@ -1969,7 +1973,7 @@
} }
/********************************************************************* /*********************************************************************
* 监控数组:repeat配合使用 * * 监控数组:for配合使用 *
**********************************************************************/ **********************************************************************/
var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice'] var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice']
@ -3401,7 +3405,7 @@
for (var i = 0, attr; (attr = attributes[i++]); ) { for (var i = 0, attr; (attr = attributes[i++]); ) {
var name = attr.name var name = attr.name
if (uniq[name]) { if (uniq[name]) {
//IE8下:repeat,:with BUG //IE8下:for BUG
continue continue
} }
uniq[name] = 1 uniq[name] = 1
@ -3480,7 +3484,7 @@
} }
} }
var rnoscanAttrBinding = /^if|widget|repeat$/ var rnoscanAttrBinding = /^if|for$/
var rnoscanNodeBinding = /^html|include$/ var rnoscanNodeBinding = /^html|include$/
function scanNodeList(elem, vmodels) { function scanNodeList(elem, vmodels) {
@ -3546,7 +3550,7 @@
} }
function scanTag(elem, vmodels) { function scanTag(elem, vmodels) {
//扫描顺序 skip(0) --> anot(1) --> :if(10) --> :repeat(90) //扫描顺序 skip(0) --> anot(1) --> :if(10) --> :for(90)
//--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后 //--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后
var skip = elem.getAttribute('skip') var skip = elem.getAttribute('skip')
var node = elem.getAttributeNode('anot') var node = elem.getAttributeNode('anot')
@ -5570,7 +5574,7 @@
} }
}) })
Anot.directive('repeat', { Anot.directive('for', {
priority: 90, priority: 90,
init: function(binding) { init: function(binding) {
var type = binding.type var type = binding.type
@ -5579,9 +5583,14 @@
var elem = binding.element var elem = binding.element
if (elem.nodeType === 1) { if (elem.nodeType === 1) {
var vars = binding.expr.split(' in ')
binding.expr = vars.pop()
if (vars.length) {
vars = vars.pop().split(/\s+/)
}
binding.vars = vars
elem.removeAttribute(binding.name) elem.removeAttribute(binding.name)
effectBinding(elem, binding) effectBinding(elem, binding)
binding.param = binding.param || 'el'
var rendered = getBindingCallback( var rendered = getBindingCallback(
elem, elem,
'data-rendered', 'data-rendered',
@ -5615,12 +5624,28 @@
var binding = this var binding = this
var xtype = this.xtype var xtype = this.xtype
if (xtype === 'array') {
if (!this.vars.length) {
this.vars.push('$index', 'el')
} else if (this.vars.length === 1) {
this.vars.unshift('$index')
}
this.param = this.vars[1]
} else {
this.param = '__el__'
if (!this.vars.length) {
this.vars.push('$key', '$val')
} else if (this.vars.length === 1) {
this.vars.push('$val')
}
}
this.enterCount += 1 this.enterCount += 1
var init = !oldValue var init = !oldValue
if (init) { if (init) {
binding.$outer = {} binding.$outer = {}
var check0 = '$key' var check0 = this.vars[0]
var check1 = '$val' var check1 = this.vars[1]
if (xtype === 'array') { if (xtype === 'array') {
check0 = '$first' check0 = '$first'
check1 = '$last' check1 = '$last'
@ -5685,9 +5710,12 @@
} }
} else { } else {
action = 'append' action = 'append'
proxy.$key = keyOrId proxy[check0] = keyOrId
proxy.$val = value[keyOrId] //key proxy[check1] = value[keyOrId] //key
proxy[param] = { $key: proxy.$key, $val: proxy.$val } var tmp = {}
tmp[check0] = proxy[check0]
tmp[check1] = proxy[check1]
proxy[param] = tmp
} }
this.cache[keyOrId] = proxy this.cache[keyOrId] = proxy
var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false)) var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false))
@ -5717,8 +5745,9 @@
if (xtype === 'array') { if (xtype === 'array') {
proxy.$first = i === 0 proxy.$first = i === 0
proxy.$last = i === length - 1 proxy.$last = i === length - 1
proxy[this.vars[0]] = proxy.$index
} else { } else {
proxy.$val = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况 proxy[check1] = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况
} }
proxies.push(proxy) proxies.push(proxy)
} }
@ -5792,7 +5821,7 @@
} }
} }
//repeat --> duplex // :for --> duplex
;(function(args) { ;(function(args) {
_parent.args = args _parent.args = args
if (_parent.msRendered) { if (_parent.msRendered) {
@ -5905,13 +5934,16 @@
binding.$repeat.removeAt(proxy.$index) binding.$repeat.removeAt(proxy.$index)
} }
var param = binding.param var param = binding.param
proxy.$watch(param, function(a) { proxy.$watch(param, function(val) {
var index = proxy.$index var index = proxy.$index
binding.$repeat[index] = a binding.$repeat[index] = val
}) })
} else { } else {
proxy.$watch('$val', function fn(a) { var __k__ = binding.vars[0]
binding.$repeat[proxy.$key] = a var __v__ = binding.vars[1]
proxy.$up.$watch(binding.expr + '.' + proxy[__k__], function(val) {
proxy[binding.param][__v__] = val
proxy[__v__] = val
}) })
} }
} }
@ -5929,12 +5961,14 @@
} }
} }
if (!proxy) { if (!proxy) {
proxy = eachProxyFactory(itemName) proxy = eachProxyFactory(data)
} }
return proxy return proxy
} }
function eachProxyFactory(itemName) { function eachProxyFactory(data) {
var itemName = data.param || 'el'
var __k__ = data.vars[0]
var source = { var source = {
$outer: {}, $outer: {},
$index: 0, $index: 0,
@ -5945,12 +5979,14 @@
$last: false, $last: false,
$remove: Anot.noop $remove: Anot.noop
} }
source[__k__] = 0
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$last: 1, $last: 1,
$first: 1, $first: 1,
$index: 1 $index: 1
} }
force[__k__] = 1
force[itemName] = 1 force[itemName] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
@ -5965,26 +6001,28 @@
var withProxyPool = [] var withProxyPool = []
function withProxyAgent(data) { function withProxyAgent(data) {
var itemName = data.param || 'el' return withProxyPool.pop() || withProxyFactory(data)
return withProxyPool.pop() || withProxyFactory(itemName)
} }
function withProxyFactory(itemName) { function withProxyFactory(data) {
var itemName = data.param || '__el__'
var __k__ = data.vars[0]
var __v__ = data.vars[1]
var source = { var source = {
$key: '',
$val: NaN,
$index: 0, $index: 0,
$oldIndex: 0, $oldIndex: 0,
$outer: {}, $outer: {},
$anchor: null $anchor: null
} }
source[__k__] = ''
source[__v__] = NaN
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$key: 1, __el__: 1,
$val: 1,
$index: 1 $index: 1
} }
force[itemName] = 1 force[__k__] = 1
force[__v__] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
{ {

View File

@ -1554,7 +1554,7 @@ const _Anot = (function() {
} }
//一些不需要被监听的属性 //一些不需要被监听的属性
var $$skipArray = oneObject( var kernelProps = oneObject(
'$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors' '$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors'
) )
@ -1567,6 +1567,11 @@ const _Anot = (function() {
return observeObject(source, options) return observeObject(source, options)
} }
function isSkip(k) {
return
k.charAt(0) === '$' || k.slice(0, 2) === '__' || kernelProps[k]
}
//监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现 //监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现
//监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴 //监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴
// 通过比较前后代理VM顺序实现 // 通过比较前后代理VM顺序实现
@ -1591,7 +1596,7 @@ const _Anot = (function() {
var hasOwn = {} var hasOwn = {}
var skip = [] var skip = []
var simple = [] var simple = []
var $skipArray = {} var userSkip = {}
// 提取 source中的配置项, 并删除相应字段 // 提取 source中的配置项, 并删除相应字段
var state = source.state var state = source.state
var computed = source.computed var computed = source.computed
@ -1607,7 +1612,7 @@ const _Anot = (function() {
delete source.watch delete source.watch
if (source.skip) { if (source.skip) {
$skipArray = oneObject(source.skip) userSkip = oneObject(source.skip)
delete source.skip delete source.skip
} }
@ -1620,14 +1625,13 @@ const _Anot = (function() {
} }
for (name in state) { for (name in state) {
var value = state[name] var value = state[name]
if (!$$skipArray[name]) { if (!kernelProps[name]) {
hasOwn[name] = true hasOwn[name] = true
} }
if ( if (
typeof value === 'function' || typeof value === 'function' ||
(value && value.nodeName && value.nodeType > 0) || (value && value.nodeName && value.nodeType > 0) ||
(!force[name] && (!force[name] && (isSkip(name) || userSkip[name]))
(name.charAt(0) === '$' || $$skipArray[name] || $skipArray[name]))
) { ) {
skip.push(name) skip.push(name)
} else if (isComputed(value)) { } else if (isComputed(value)) {
@ -1954,7 +1958,7 @@ const _Anot = (function() {
} }
/********************************************************************* /*********************************************************************
* 监控数组:repeat配合使用 * * 监控数组:for配合使用 *
**********************************************************************/ **********************************************************************/
var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice'] var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice']
@ -3386,7 +3390,7 @@ const _Anot = (function() {
for (var i = 0, attr; (attr = attributes[i++]); ) { for (var i = 0, attr; (attr = attributes[i++]); ) {
var name = attr.name var name = attr.name
if (uniq[name]) { if (uniq[name]) {
//IE8下:repeat,:with BUG //IE8下:for BUG
continue continue
} }
uniq[name] = 1 uniq[name] = 1
@ -3465,7 +3469,7 @@ const _Anot = (function() {
} }
} }
var rnoscanAttrBinding = /^if|widget|repeat$/ var rnoscanAttrBinding = /^if|for$/
var rnoscanNodeBinding = /^html|include$/ var rnoscanNodeBinding = /^html|include$/
function scanNodeList(elem, vmodels) { function scanNodeList(elem, vmodels) {
@ -3531,7 +3535,7 @@ const _Anot = (function() {
} }
function scanTag(elem, vmodels) { function scanTag(elem, vmodels) {
//扫描顺序 skip(0) --> anot(1) --> :if(10) --> :repeat(90) //扫描顺序 skip(0) --> anot(1) --> :if(10) --> :for(90)
//--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后 //--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后
var skip = elem.getAttribute('skip') var skip = elem.getAttribute('skip')
var node = elem.getAttributeNode('anot') var node = elem.getAttributeNode('anot')
@ -5555,7 +5559,7 @@ const _Anot = (function() {
} }
}) })
Anot.directive('repeat', { Anot.directive('for', {
priority: 90, priority: 90,
init: function(binding) { init: function(binding) {
var type = binding.type var type = binding.type
@ -5564,9 +5568,14 @@ const _Anot = (function() {
var elem = binding.element var elem = binding.element
if (elem.nodeType === 1) { if (elem.nodeType === 1) {
var vars = binding.expr.split(' in ')
binding.expr = vars.pop()
if (vars.length) {
vars = vars.pop().split(/\s+/)
}
binding.vars = vars
elem.removeAttribute(binding.name) elem.removeAttribute(binding.name)
effectBinding(elem, binding) effectBinding(elem, binding)
binding.param = binding.param || 'el'
var rendered = getBindingCallback( var rendered = getBindingCallback(
elem, elem,
'data-rendered', 'data-rendered',
@ -5600,12 +5609,28 @@ const _Anot = (function() {
var binding = this var binding = this
var xtype = this.xtype var xtype = this.xtype
if (xtype === 'array') {
if (!this.vars.length) {
this.vars.push('$index', 'el')
} else if (this.vars.length === 1) {
this.vars.unshift('$index')
}
this.param = this.vars[1]
} else {
this.param = '__el__'
if (!this.vars.length) {
this.vars.push('$key', '$val')
} else if (this.vars.length === 1) {
this.vars.push('$val')
}
}
this.enterCount += 1 this.enterCount += 1
var init = !oldValue var init = !oldValue
if (init) { if (init) {
binding.$outer = {} binding.$outer = {}
var check0 = '$key' var check0 = this.vars[0]
var check1 = '$val' var check1 = this.vars[1]
if (xtype === 'array') { if (xtype === 'array') {
check0 = '$first' check0 = '$first'
check1 = '$last' check1 = '$last'
@ -5670,9 +5695,12 @@ const _Anot = (function() {
} }
} else { } else {
action = 'append' action = 'append'
proxy.$key = keyOrId proxy[check0] = keyOrId
proxy.$val = value[keyOrId] //key proxy[check1] = value[keyOrId] //key
proxy[param] = { $key: proxy.$key, $val: proxy.$val } var tmp = {}
tmp[check0] = proxy[check0]
tmp[check1] = proxy[check1]
proxy[param] = tmp
} }
this.cache[keyOrId] = proxy this.cache[keyOrId] = proxy
var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false)) var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false))
@ -5702,8 +5730,9 @@ const _Anot = (function() {
if (xtype === 'array') { if (xtype === 'array') {
proxy.$first = i === 0 proxy.$first = i === 0
proxy.$last = i === length - 1 proxy.$last = i === length - 1
proxy[this.vars[0]] = proxy.$index
} else { } else {
proxy.$val = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况 proxy[check1] = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况
} }
proxies.push(proxy) proxies.push(proxy)
} }
@ -5777,7 +5806,7 @@ const _Anot = (function() {
} }
} }
//repeat --> duplex // :for --> duplex
;(function(args) { ;(function(args) {
_parent.args = args _parent.args = args
if (_parent.msRendered) { if (_parent.msRendered) {
@ -5890,13 +5919,16 @@ const _Anot = (function() {
binding.$repeat.removeAt(proxy.$index) binding.$repeat.removeAt(proxy.$index)
} }
var param = binding.param var param = binding.param
proxy.$watch(param, function(a) { proxy.$watch(param, function(val) {
var index = proxy.$index var index = proxy.$index
binding.$repeat[index] = a binding.$repeat[index] = val
}) })
} else { } else {
proxy.$watch('$val', function fn(a) { var __k__ = binding.vars[0]
binding.$repeat[proxy.$key] = a var __v__ = binding.vars[1]
proxy.$up.$watch(binding.expr + '.' + proxy[__k__], function(val) {
proxy[binding.param][__v__] = val
proxy[__v__] = val
}) })
} }
} }
@ -5914,12 +5946,14 @@ const _Anot = (function() {
} }
} }
if (!proxy) { if (!proxy) {
proxy = eachProxyFactory(itemName) proxy = eachProxyFactory(data)
} }
return proxy return proxy
} }
function eachProxyFactory(itemName) { function eachProxyFactory(data) {
var itemName = data.param || 'el'
var __k__ = data.vars[0]
var source = { var source = {
$outer: {}, $outer: {},
$index: 0, $index: 0,
@ -5930,12 +5964,14 @@ const _Anot = (function() {
$last: false, $last: false,
$remove: Anot.noop $remove: Anot.noop
} }
source[__k__] = 0
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$last: 1, $last: 1,
$first: 1, $first: 1,
$index: 1 $index: 1
} }
force[__k__] = 1
force[itemName] = 1 force[itemName] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
@ -5950,26 +5986,28 @@ const _Anot = (function() {
var withProxyPool = [] var withProxyPool = []
function withProxyAgent(data) { function withProxyAgent(data) {
var itemName = data.param || 'el' return withProxyPool.pop() || withProxyFactory(data)
return withProxyPool.pop() || withProxyFactory(itemName)
} }
function withProxyFactory(itemName) { function withProxyFactory(data) {
var itemName = data.param || '__el__'
var __k__ = data.vars[0]
var __v__ = data.vars[1]
var source = { var source = {
$key: '',
$val: NaN,
$index: 0, $index: 0,
$oldIndex: 0, $oldIndex: 0,
$outer: {}, $outer: {},
$anchor: null $anchor: null
} }
source[__k__] = ''
source[__v__] = NaN
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$key: 1, __el__: 1,
$val: 1,
$index: 1 $index: 1
} }
force[itemName] = 1 force[__k__] = 1
force[__v__] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
{ {

View File

@ -1569,7 +1569,7 @@
} }
//一些不需要被监听的属性 //一些不需要被监听的属性
var $$skipArray = oneObject( var kernelProps = oneObject(
'$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors' '$id,$watch,$fire,$events,$model,$active,$pathname,$up,$ups,$track,$accessors'
) )
@ -1582,6 +1582,11 @@
return observeObject(source, options) return observeObject(source, options)
} }
function isSkip(k) {
return
k.charAt(0) === '$' || k.slice(0, 2) === '__' || kernelProps[k]
}
//监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现 //监听对象属性值的变化(注意,数组元素不是数组的属性),通过对劫持当前对象的访问器实现
//监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴 //监听对象或数组的结构变化, 对对象的键值对进行增删重排, 或对数组的进行增删重排,都属于这范畴
// 通过比较前后代理VM顺序实现 // 通过比较前后代理VM顺序实现
@ -1606,7 +1611,7 @@
var hasOwn = {} var hasOwn = {}
var skip = [] var skip = []
var simple = [] var simple = []
var $skipArray = {} var userSkip = {}
// 提取 source中的配置项, 并删除相应字段 // 提取 source中的配置项, 并删除相应字段
var state = source.state var state = source.state
var computed = source.computed var computed = source.computed
@ -1622,7 +1627,7 @@
delete source.watch delete source.watch
if (source.skip) { if (source.skip) {
$skipArray = oneObject(source.skip) userSkip = oneObject(source.skip)
delete source.skip delete source.skip
} }
@ -1635,14 +1640,13 @@
} }
for (name in state) { for (name in state) {
var value = state[name] var value = state[name]
if (!$$skipArray[name]) { if (!kernelProps[name]) {
hasOwn[name] = true hasOwn[name] = true
} }
if ( if (
typeof value === 'function' || typeof value === 'function' ||
(value && value.nodeName && value.nodeType > 0) || (value && value.nodeName && value.nodeType > 0) ||
(!force[name] && (!force[name] && (isSkip(name) || userSkip[name]))
(name.charAt(0) === '$' || $$skipArray[name] || $skipArray[name]))
) { ) {
skip.push(name) skip.push(name)
} else if (isComputed(value)) { } else if (isComputed(value)) {
@ -1969,7 +1973,7 @@
} }
/********************************************************************* /*********************************************************************
* 监控数组:repeat配合使用 * * 监控数组:for配合使用 *
**********************************************************************/ **********************************************************************/
var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice'] var arrayMethods = ['push', 'pop', 'shift', 'unshift', 'splice']
@ -3401,7 +3405,7 @@
for (var i = 0, attr; (attr = attributes[i++]); ) { for (var i = 0, attr; (attr = attributes[i++]); ) {
var name = attr.name var name = attr.name
if (uniq[name]) { if (uniq[name]) {
//IE8下:repeat,:with BUG //IE8下:for BUG
continue continue
} }
uniq[name] = 1 uniq[name] = 1
@ -3480,7 +3484,7 @@
} }
} }
var rnoscanAttrBinding = /^if|widget|repeat$/ var rnoscanAttrBinding = /^if|for$/
var rnoscanNodeBinding = /^html|include$/ var rnoscanNodeBinding = /^html|include$/
function scanNodeList(elem, vmodels) { function scanNodeList(elem, vmodels) {
@ -3546,7 +3550,7 @@
} }
function scanTag(elem, vmodels) { function scanTag(elem, vmodels) {
//扫描顺序 skip(0) --> anot(1) --> :if(10) --> :repeat(90) //扫描顺序 skip(0) --> anot(1) --> :if(10) --> :for(90)
//--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后 //--> :if-loop(110) --> :attr(970) ...--> :duplex(2000)垫后
var skip = elem.getAttribute('skip') var skip = elem.getAttribute('skip')
var node = elem.getAttributeNode('anot') var node = elem.getAttributeNode('anot')
@ -5570,7 +5574,7 @@
} }
}) })
Anot.directive('repeat', { Anot.directive('for', {
priority: 90, priority: 90,
init: function(binding) { init: function(binding) {
var type = binding.type var type = binding.type
@ -5579,9 +5583,14 @@
var elem = binding.element var elem = binding.element
if (elem.nodeType === 1) { if (elem.nodeType === 1) {
var vars = binding.expr.split(' in ')
binding.expr = vars.pop()
if (vars.length) {
vars = vars.pop().split(/\s+/)
}
binding.vars = vars
elem.removeAttribute(binding.name) elem.removeAttribute(binding.name)
effectBinding(elem, binding) effectBinding(elem, binding)
binding.param = binding.param || 'el'
var rendered = getBindingCallback( var rendered = getBindingCallback(
elem, elem,
'data-rendered', 'data-rendered',
@ -5615,12 +5624,28 @@
var binding = this var binding = this
var xtype = this.xtype var xtype = this.xtype
if (xtype === 'array') {
if (!this.vars.length) {
this.vars.push('$index', 'el')
} else if (this.vars.length === 1) {
this.vars.unshift('$index')
}
this.param = this.vars[1]
} else {
this.param = '__el__'
if (!this.vars.length) {
this.vars.push('$key', '$val')
} else if (this.vars.length === 1) {
this.vars.push('$val')
}
}
this.enterCount += 1 this.enterCount += 1
var init = !oldValue var init = !oldValue
if (init) { if (init) {
binding.$outer = {} binding.$outer = {}
var check0 = '$key' var check0 = this.vars[0]
var check1 = '$val' var check1 = this.vars[1]
if (xtype === 'array') { if (xtype === 'array') {
check0 = '$first' check0 = '$first'
check1 = '$last' check1 = '$last'
@ -5685,9 +5710,12 @@
} }
} else { } else {
action = 'append' action = 'append'
proxy.$key = keyOrId proxy[check0] = keyOrId
proxy.$val = value[keyOrId] //key proxy[check1] = value[keyOrId] //key
proxy[param] = { $key: proxy.$key, $val: proxy.$val } var tmp = {}
tmp[check0] = proxy[check0]
tmp[check1] = proxy[check1]
proxy[param] = tmp
} }
this.cache[keyOrId] = proxy this.cache[keyOrId] = proxy
var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false)) var node = proxy.$anchor || (proxy.$anchor = elem.cloneNode(false))
@ -5717,8 +5745,9 @@
if (xtype === 'array') { if (xtype === 'array') {
proxy.$first = i === 0 proxy.$first = i === 0
proxy.$last = i === length - 1 proxy.$last = i === length - 1
proxy[this.vars[0]] = proxy.$index
} else { } else {
proxy.$val = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况 proxy[check1] = toJson(value[keyOrId]) //这里是处理vm.object = newObject的情况
} }
proxies.push(proxy) proxies.push(proxy)
} }
@ -5792,7 +5821,7 @@
} }
} }
//repeat --> duplex // :for --> duplex
;(function(args) { ;(function(args) {
_parent.args = args _parent.args = args
if (_parent.msRendered) { if (_parent.msRendered) {
@ -5905,13 +5934,16 @@
binding.$repeat.removeAt(proxy.$index) binding.$repeat.removeAt(proxy.$index)
} }
var param = binding.param var param = binding.param
proxy.$watch(param, function(a) { proxy.$watch(param, function(val) {
var index = proxy.$index var index = proxy.$index
binding.$repeat[index] = a binding.$repeat[index] = val
}) })
} else { } else {
proxy.$watch('$val', function fn(a) { var __k__ = binding.vars[0]
binding.$repeat[proxy.$key] = a var __v__ = binding.vars[1]
proxy.$up.$watch(binding.expr + '.' + proxy[__k__], function(val) {
proxy[binding.param][__v__] = val
proxy[__v__] = val
}) })
} }
} }
@ -5929,12 +5961,14 @@
} }
} }
if (!proxy) { if (!proxy) {
proxy = eachProxyFactory(itemName) proxy = eachProxyFactory(data)
} }
return proxy return proxy
} }
function eachProxyFactory(itemName) { function eachProxyFactory(data) {
var itemName = data.param || 'el'
var __k__ = data.vars[0]
var source = { var source = {
$outer: {}, $outer: {},
$index: 0, $index: 0,
@ -5945,12 +5979,14 @@
$last: false, $last: false,
$remove: Anot.noop $remove: Anot.noop
} }
source[__k__] = 0
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$last: 1, $last: 1,
$first: 1, $first: 1,
$index: 1 $index: 1
} }
force[__k__] = 1
force[itemName] = 1 force[itemName] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
@ -5965,26 +6001,28 @@
var withProxyPool = [] var withProxyPool = []
function withProxyAgent(data) { function withProxyAgent(data) {
var itemName = data.param || 'el' return withProxyPool.pop() || withProxyFactory(data)
return withProxyPool.pop() || withProxyFactory(itemName)
} }
function withProxyFactory(itemName) { function withProxyFactory(data) {
var itemName = data.param || '__el__'
var __k__ = data.vars[0]
var __v__ = data.vars[1]
var source = { var source = {
$key: '',
$val: NaN,
$index: 0, $index: 0,
$oldIndex: 0, $oldIndex: 0,
$outer: {}, $outer: {},
$anchor: null $anchor: null
} }
source[__k__] = ''
source[__v__] = NaN
source[itemName] = NaN source[itemName] = NaN
var force = { var force = {
$key: 1, __el__: 1,
$val: 1,
$index: 1 $index: 1
} }
force[itemName] = 1 force[__k__] = 1
force[__v__] = 1
var proxy = modelFactory( var proxy = modelFactory(
{ state: source }, { state: source },
{ {

View File

@ -164,7 +164,7 @@ export default Anot.component('datepicker', {
<section class="tr do-fn-cl"> <section class="tr do-fn-cl">
<span class="td" <span class="td"
:class="{weeken:el.weeken, disabled: el.disabled, selected: el.selected}" :class="{weeken:el.weeken, disabled: el.disabled, selected: el.selected}"
:repeat="calendar.list" :for="calendar.list"
:click="pick(el)" :click="pick(el)"
:text="el.day"></span> :text="el.day"></span>
</section> </section>

View File

@ -122,7 +122,7 @@ const fixCont = function(vm, tool) {
<span class="col">操作</span> <span class="col">操作</span>
</li> </li>
<li class="tbody"> <li class="tbody">
<p :repeat="uploadQueue"> <p :for="uploadQueue">
<span <span
class="col do-fn-ell" class="col do-fn-ell"
:text="el.name" :text="el.name"
@ -137,7 +137,7 @@ const fixCont = function(vm, tool) {
<ul class="list-box"> <ul class="list-box">
<li <li
class="item" class="item"
:repeat="attachList" :for="attachList"
:layer-tips="el.name" :layer-tips="el.name"
:click="insert(el)"> :click="insert(el)">

View File

@ -239,7 +239,7 @@ const addon = {
}, },
content: ` content: `
<ul class="do-meditor-face"> <ul class="do-meditor-face">
<li class="item" :repeat="arr"> <li class="item" :for="arr">
<span :html="el" :click="insert(el)"></span> <span :html="el" :click="insert(el)"></span>
</li> </li>
</ul>`, </ul>`,
@ -273,9 +273,9 @@ const addon = {
}), }),
content: ` content: `
<ul class="do-meditor-table" ref="table"> <ul class="do-meditor-table" ref="table">
<li :repeat="matrix"> <li :for="matrix">
<span <span
:repeat-o="el" :for="o in el"
:class="{active: o.v}" :class="{active: o.v}"
:data="{x: $index, y: $outer.$index}"></span> :data="{x: $index, y: $outer.$index}"></span>
</li> </li>
@ -442,7 +442,7 @@ const addon = {
<section class="do-fn-cl"> <section class="do-fn-cl">
<span class="label">语言类型</span> <span class="label">语言类型</span>
<select :duplex="lang"> <select :duplex="lang">
<option :repeat="$lang" :attr-value="el.id">{{el.name || el.id}}</option> <option :for="$lang" :attr-value="el.id">{{el.name || el.id}}</option>
</select> </select>
</section> </section>
<section> <section>

View File

@ -79,7 +79,7 @@ const tmpls = {
:data="{to: parseUrl(currPage + 1)}" :data="{to: parseUrl(currPage + 1)}"
:click="go(currPage + 1, $event)"></button>`, :click="go(currPage + 1, $event)"></button>`,
pager: `<button class="page" pager: `<button class="page"
:repeat="pageList" :for="pageList"
:css="{'border-radius': props.radius}" :css="{'border-radius': props.radius}"
:attr="{disabled: '...' === el || currPage === el}" :attr="{disabled: '...' === el || currPage === el}"
:data="{to: parseUrl(el)}" :data="{to: parseUrl(el)}"

View File

@ -67,7 +67,7 @@ export default Anot.component('tree', {
let { multiCheck } = this let { multiCheck } = this
return ` return `
<section class="do-tree__item" :repeat="list" :class="{open: el.__open__, dir: el.children}"> <section class="do-tree__item" :for="list" :class="{open: el.__open__, dir: el.children}">
<em <em
:class="{ :class="{
'do-icon-txt': !el.children, 'do-icon-txt': !el.children,