syncRoots method

void syncRoots(
  1. List<TreeNode<TKey, TData>> desired, {
  2. List<TreeNode<TKey, TData>> childrenOf(
    1. TKey key
    )?,
  3. bool animate = true,
})

Syncs the root nodes to match desired.

Roots present in the tree but absent from desired are removed. Roots in desired but not in the tree are inserted at the correct index. The order of desired is respected.

If childrenOf is provided, it is called recursively for every node in the desired tree (roots and their descendants) to sync children at all depths. Return an empty list for leaf nodes. If a re-added node was previously expanded (and expansionMemory is nonzero), it is automatically expanded after its children are set.

childrenOf must be a PURE function of its argument. The desired tree is walked twice (descendant collection, then the diff), and the answer is memoized across both, so it is consulted exactly once per node per sync. Returning different children for the same key within one sync is a caller bug and the second answer is not observed.

Reparent through removed root. A descendant of a root that is being removed in this sync, but that appears elsewhere in the desired tree (under a different parent), is animated (slid) into its new position rather than purged with the old root. This is implemented by deferring root removal until after the recursive children sync has had a chance to call TreeController.moveNode for every cross-parent reparent. The old root then exits as a clean separate animation on the (now-empty or non-desired-residue) subtree it left.

Set animate to false to suppress animations (useful for initial setup).

Implementation

void syncRoots(
  List<TreeNode<TKey, TData>> desired, {
  List<TreeNode<TKey, TData>> Function(TKey key)? childrenOf,
  bool animate = true,
}) {
  _assertNoDuplicateKeys(desired, "syncRoots");
  _controller.runBatch(() {
    _syncRootsImpl(desired, childrenOf: childrenOf, animate: animate);
  });
}