UNPKG

neft

Version:

Universal Platform

191 lines (139 loc) 4.45 kB
'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 @__name__ = 'Iterator' @__path__ = 'File.Iterator' JSON_CTOR_ID = @JSON_CTOR_ID = File.JSON_CTORS.push(Iterator) - 1 i = 1 JSON_NAME = i++ JSON_NODE = i++ JSON_TEXT = i++ JSON_ARGS_LENGTH = @JSON_ARGS_LENGTH = i @_fromJSON = (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 @file.isRendered and name is 'n-each' @update() visibilityChangeListener = (oldVal) -> if @file.isRendered and oldVal is false and not @node.data @update() constructor: (@file, @node, @name) -> assert.instanceOf @file, File assert.instanceOf @node, File.Element assert.isString @name assert.notLengthOf @name, 0 @usedComponents = [] @text = '' @data = null @isRendered = false @node.onPropsChange propsChangeListener, @ @node.onVisibleChange visibilityChangeListener, @ `//<development>` if @constructor is Iterator Object.preventExtensions @ `//</development>` render: -> unless @node.visible return each = @node.props['n-each'] # stop if nothing changed if each is @data 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 @data = array = each # listen on changes if each instanceof List each.onChange @updateItem, @ each.onInsert @insertItem, @ each.onPop @popItem, @ # add items for _, i in array @insertItem i @isRendered = true null revert: -> {data} = @ if data @clearData() if data instanceof List data.onChange.disconnect @updateItem, @ data.onInsert.disconnect @insertItem, @ data.onPop.disconnect @popItem, @ @data = null @isRendered = false update: -> @revert() @render() clearData: -> assert.isObject @data while length = @usedComponents.length @popItem length - 1 @ updateItem: (elem, i) -> unless i? i = elem assert.isObject @data assert.isInteger i @popItem i @insertItem i @ insertItem: (elem, i) -> unless i? i = elem assert.isObject @data assert.isInteger i {data} = @ usedComponent = File.factory @name @usedComponents.splice i, 0, usedComponent each = data item = data[i] # replace newChild = usedComponent.node newChild.parent = @node newChild.index = i # render component newChild.props.set 'each', each newChild.props.set 'index', i newChild.props.set 'item', item usedComponent.scope = @file.scope usedComponent.render @file.inputProps, @file.context, null, @file.inputRefs # signal usedComponent.onReplaceByUse.emit @ File.emitNodeSignal usedComponent, 'n-onReplaceByUse', @ @ popItem: (elem, i) -> unless i? i = elem assert.isObject @data assert.isInteger i @node.children[i].parent = undefined usedComponent = @usedComponents[i] usedComponent.scope = null usedComponent.revert().destroy() @usedComponents.splice i, 1 @ clone: (original, file) -> node = original.node.getCopiedElement @node, file.node new Iterator file, node, @name toJSON: (key, arr) -> unless arr arr = new Array JSON_ARGS_LENGTH arr[0] = JSON_CTOR_ID arr[JSON_NAME] = @name arr[JSON_NODE] = @node.getAccessPath @file.node arr[JSON_TEXT] = @text arr