updateItemByKey method

void updateItemByKey(
  1. K key,
  2. T newItem
)

Updates an item by its key.

Handles child hierarchy changes: removes stale descendants, registers new ones.

Implementation

void updateItemByKey(K key, T newItem) {
  final existing = _itemsMap[key];
  if (existing == null) throw ArgumentError.value(key, 'key', 'Item not found');

  final rawChildren = getChildren(newItem);
  final newChildKeys = rawChildren != null && rawChildren.isNotEmpty ? rawChildren.map(itemKey).toList() : null;

  _itemsMap[key] = itemFactory(newItem, parentKey: existing.parentKey, childrenKeys: newChildKeys, level: existing.level);

  final oldChildKeys = existing.childrenKeys ?? const [];
  final newKeysSet = (newChildKeys ?? const []).toSet();
  final removedDescendants = <K>{};

  for (final oldKey in oldChildKeys) {
    if (!newKeysSet.contains(oldKey)) {
      final descendants = getDescendantsOfKey(oldKey)..add(oldKey);
      removedDescendants.addAll(descendants);
      _itemsMap.removeWhere((k, _) => descendants.contains(k));
      if (_useLocalPaginationItems) {
        _localPaginationItems.removeWhere((x) => descendants.contains(x.key));
      }
    }
  }

  if (isHierarchical && rawChildren != null) {
    for (final child in rawChildren) {
      _registerRecursive(child, parentKey: key, level: existing.level + 1);
    }
  }

  if (_useLocalPaginationItems) {
    final idx = _localPaginationItems.indexWhere((x) => x.key == key);
    if (idx != -1) _localPaginationItems[idx] = _itemsMap[key]!;
  }

  var newDisplayItems =
      removedDescendants.isEmpty ? value.displayItems : value.displayItems.where((x) => !removedDescendants.contains(x.key)).toList();

  final idx = newDisplayItems.indexWhere((x) => x.key == key);
  if (idx > -1) newDisplayItems = newDisplayItems.copyWithReplacedAt(idx, _itemsMap[key]!);

  // If childrenKeys changed, sync the parent entry (the updated item itself IS the parent here).
  if (existing.parentKey != null) {
    _syncParentInLocalAndDisplay(existing.parentKey as K);
  }

  updateState(
    who: 'updateItem',
    displayItems: newDisplayItems,
    selectedKeys: removedDescendants.isEmpty ? null : (copyKeySet(value.selectedKeys)..removeAll(removedDescendants)),
    expandedKeys: removedDescendants.isEmpty ? null : (copyKeySet(value.expandedKeys)..removeAll(removedDescendants)),
    totalItems: removedDescendants.isEmpty ? null : value.totalItems - removedDescendants.length,
  );
}