c4620bf8 by Michael Richards

Merge pull request #163 from mikeric/each-binder-improvements

Routine performance improvements for each-* binder
2 parents f8d23781 a8487e71
...@@ -368,46 +368,55 @@ Rivets.binders = ...@@ -368,46 +368,55 @@ Rivets.binders =
368 368
369 "each-*": 369 "each-*":
370 block: true 370 block: true
371 bind: (el, collection) -> 371
372 el.removeAttribute ['data', @view.config.prefix, @type].join('-').replace '--', '-' 372 bind: (el) ->
373 unbind: (el, collection) -> 373 attr = ['data', @view.config.prefix, @type].join('-').replace '--', '-'
374 view.unbind() for view in @iterated if @iterated?
375 routine: (el, collection) ->
376 if @iterated?
377 for view in @iterated
378 view.unbind()
379 e.parentNode.removeChild e for e in view.els
380 else
381 @marker = document.createComment " rivets: #{@type} " 374 @marker = document.createComment " rivets: #{@type} "
375 @iterated = []
376
377 el.removeAttribute attr
382 el.parentNode.insertBefore @marker, el 378 el.parentNode.insertBefore @marker, el
383 el.parentNode.removeChild el 379 el.parentNode.removeChild el
384 380
385 @iterated = [] 381 unbind: (el) ->
382 view.unbind() for view in @iterated if @iterated?
386 383
387 if collection 384 routine: (el, collection) ->
388 for item in collection 385 modelName = @args[0]
386 collection = collection or []
387
388 if @iterated.length > collection.length
389 for i in Array @iterated.length - collection.length
390 view = @iterated.pop()
391 view.unbind()
392 @marker.parentNode.removeChild view.els[0]
393
394 for model, index in collection
389 data = {} 395 data = {}
390 data[n] = m for n, m of @view.models 396 data[modelName] = model
391 data[@args[0]] = item 397
392 itemEl = el.cloneNode true 398 if not @iterated[index]?
399 for key, model of @view.models
400 data[key] = model
393 401
394 previous = if @iterated.length 402 previous = if @iterated.length
395 @iterated[@iterated.length - 1].els[0] 403 @iterated[@iterated.length - 1].els[0]
396 else 404 else
397 @marker 405 @marker
398 406
399 @marker.parentNode.insertBefore itemEl, previous.nextSibling ? null
400 options = 407 options =
401 binders: @view.options.binders 408 binders: @view.options.binders
402 formatters: @view.options.binders 409 formatters: @view.options.formatters
403 config: {} 410 config: {}
404 options.config[k] = v for k, v of @view.options.config if @view.options.config 411
405 # Ensure preloadData is set to true since child elements won't get initiated otherwise until the next change (which might not be the first) 412 options.config[k] = v for k, v of @view.options.config
406 options.config.preloadData = true 413 options.config.preloadData = true
407 414
408 view = new Rivets.View(itemEl, data, options) 415 template = el.cloneNode true
409 view.bind() 416 @iterated.push rivets.bind template, data, options
410 @iterated.push view 417 @marker.parentNode.insertBefore template, previous.nextSibling
418 else if @iterated[index].models[modelName] isnt model
419 @iterated[index].update data
411 420
412 "class-*": (el, value) -> 421 "class-*": (el, value) ->
413 elClass = " #{el.className} " 422 elClass = " #{el.className} "
......