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 @marker = document.createComment " rivets: #{@type} "
375 @iterated = []
376
377 el.removeAttribute attr
378 el.parentNode.insertBefore @marker, el
379 el.parentNode.removeChild el
380
381 unbind: (el) ->
374 view.unbind() for view in @iterated if @iterated? 382 view.unbind() for view in @iterated if @iterated?
383
375 routine: (el, collection) -> 384 routine: (el, collection) ->
376 if @iterated? 385 modelName = @args[0]
377 for view in @iterated 386 collection = collection or []
387
388 if @iterated.length > collection.length
389 for i in Array @iterated.length - collection.length
390 view = @iterated.pop()
378 view.unbind() 391 view.unbind()
379 e.parentNode.removeChild e for e in view.els 392 @marker.parentNode.removeChild view.els[0]
380 else
381 @marker = document.createComment " rivets: #{@type} "
382 el.parentNode.insertBefore @marker, el
383 el.parentNode.removeChild el
384 393
385 @iterated = [] 394 for model, index in collection
395 data = {}
396 data[modelName] = model
386 397
387 if collection 398 if not @iterated[index]?
388 for item in collection 399 for key, model of @view.models
389 data = {} 400 data[key] = model
390 data[n] = m for n, m of @view.models
391 data[@args[0]] = item
392 itemEl = el.cloneNode true
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 407 options =
400 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} "
......