SteveSanderson/knockout — pull request #690 by seanami (2012-10-31 21:21:31+00:00)
Title: Add global before/after callbacks to foreach/template bindings

This is a feature request branch to add two additional callbacks to the ones that the `foreach`/`template` bindings already support (`beforeRemove`, `afterAdd`, `beforeMove`, `afterMove`). These callbacks are a bit different in that they are "global": called once each for each set of changes to the items within the binding instead of once for each different type of change (removes, adds, moves).

I've named the two new callbacks `before` and `after`, but I'm open to naming suggestions. The `before` callback fires once for each set of removes/adds/moves before any changes to the DOM are made and before any other callbacks have fired. The `after` callback is symmetrical and fires once for each set of removes/adds/moves after all changes to the DOM are made and after all other callbacks have fired. Neither callback receives any arguments, although it might be useful if they received arrays of added, removed, and moved nodes. I wanted to start simple and see what people thought.

These global callbacks give you a single opportunity to execute code before and after the DOM is modified during a mapping of an array to DOM node children. This allows you to do things like animate the transition between old and new states in a way that requires knowing the old and new location of child elements. With the current callbacks, the only callback that fires before the DOM is updated is beforeMove, so if there aren't any moves there's no way to execute code to check on old positions before the DOM is changed. Additionally, it's inefficient to execute some code after all changes to the DOM are finished today, as you have to set up some sort of async timeout that is continually cancelled and renewed during each callback for an individual element and which finally triggers once all have fired.

These callbacks are important to efficiently support the animations that we use with Knockout at Typekit, and any animations where you need to know things about position or other aspects of the DOM before and after a change. If you [check out our font browsing page](https://typekit.com/fonts), which is implemented in Knockout, the font cards are drawn with a `template` binding. When you click on a classification or other filter on the right, we animate the position of the cards to visually communicate the idea that you're narrowing down a set of items. In order to pull this off, we look at the status (removed/added/moved) and position of elements before and after the change and then set up animations between the two states.

The changes in the last few versions to the Knockout internals of foreach/template have invalidated our current approach. They're *close* to making a much simpler and more robust approach possible, but I need callbacks that will reliably allow me to inspect the DOM before and after changes.