neft
Version:
Universal Platform
191 lines (139 loc) • 4.45 kB
text/coffeescript
'use strict'
utils = require 'src/utils'
assert = require 'src/assert'
List = require 'src/list'
log = require 'src/log'
{isArray} = Array
assert = assert.scope 'View.Iterator'
log = log.scope 'View', 'Iterator'
module.exports = (File) -> class Iterator
= 'Iterator'
= 'File.Iterator'
JSON_CTOR_ID = = File.JSON_CTORS.push(Iterator) - 1
i = 1
JSON_NAME = i++
JSON_NODE = i++
JSON_TEXT = i++
JSON_ARGS_LENGTH = = i
= (file, arr, obj) ->
unless obj
node = file.node.getChildByAccessPath arr[JSON_NODE]
obj = new Iterator file, node, arr[JSON_NAME]
obj.text = arr[JSON_TEXT]
obj
propsChangeListener = (name) ->
if .isRendered and name is 'n-each'
visibilityChangeListener = (oldVal) ->
if .isRendered and oldVal is false and not .data
constructor: (, , ) ->
assert.instanceOf , File
assert.instanceOf , File.Element
assert.isString
assert.notLengthOf , 0
= []
= ''
= null
= false
.onPropsChange propsChangeListener, @
.onVisibleChange visibilityChangeListener, @
`//<development>`
if is Iterator
Object.preventExtensions @
`//</development>`
render: ->
unless .visible
return
each = .props['n-each']
# stop if nothing changed
if each is
return
# stop if no data found
if not isArray(each) and not (each instanceof List)
# log.warn "Data is not an array nor List in '#{@text}':\n#{each}"
return
# set as data
= array = each
# listen on changes
if each instanceof List
each.onChange , @
each.onInsert , @
each.onPop , @
# add items
for _, i in array
i
= true
null
revert: ->
{data} = @
if data
if data instanceof List
data.onChange.disconnect , @
data.onInsert.disconnect , @
data.onPop.disconnect , @
= null
= false
update: ->
clearData: ->
assert.isObject
while length = .length
length - 1
@
updateItem: (elem, i) ->
unless i?
i = elem
assert.isObject
assert.isInteger i
i
i
@
insertItem: (elem, i) ->
unless i?
i = elem
assert.isObject
assert.isInteger i
{data} = @
usedComponent = File.factory
.splice i, 0, usedComponent
each = data
item = data[i]
# replace
newChild = usedComponent.node
newChild.parent =
newChild.index = i
# render component
newChild.props.set 'each', each
newChild.props.set 'index', i
newChild.props.set 'item', item
usedComponent.scope = .scope
usedComponent.render .inputProps, .context, null, .inputRefs
# signal
usedComponent.onReplaceByUse.emit @
File.emitNodeSignal usedComponent, 'n-onReplaceByUse', @
@
popItem: (elem, i) ->
unless i?
i = elem
assert.isObject
assert.isInteger i
.children[i].parent = undefined
usedComponent = [i]
usedComponent.scope = null
usedComponent.revert().destroy()
.splice i, 1
@
clone: (original, file) ->
node = original.node.getCopiedElement , file.node
new Iterator file, node,
toJSON: (key, arr) ->
unless arr
arr = new Array JSON_ARGS_LENGTH
arr[0] = JSON_CTOR_ID
arr[JSON_NAME] =
arr[JSON_NODE] = .getAccessPath .node
arr[JSON_TEXT] =
arr