Creation, three-phase initialization, parent-child relationships, and update notifications.
Object → ProtoClass → SvNode → SvViewableNode → SvStyledNode → SvStorableNodeEvery node goes through the same sequence, whether freshly created or loaded from storage:
init() — Primitives and slotssuper.init()initializeSlots()Only set primitive values and simple defaults here. Don't create child objects — they may be about to arrive from the store.
finalInit() — Complex objects and relationshipssuper.finalInit()setFinalInitProto() — but only if the slot wasn't already populated from storageThis is where you detect whether the object is new or loaded:
finalInit () {
super.finalInit();
if (!this.hasStoredData()) {
this.randomizeValues();
}
}afterInit() → didInit() — Post-initialization_hasDoneInit = trueBy this point the full object graph is ready and it's safe to interact with other objects.
Always use ProtoClass.clone() rather than new. clone() runs the full three-phase sequence automatically.
Adding subnodes:
addSubnode(node) — Add to endaddSubnodeAt(node, index) — Add at specific positionparentNodedidChangeSubnodeList()Removing subnodes:
removeSubnode(node) — Remove specific nodeparentNode referencedidChangeSubnodeList()When a slot value changes, the framework fires a notification chain:
setSlotValue(newValue)
└── didUpdateSlot(slot, oldValue, newValue)
├── didUpdateSlot[SlotName](oldValue, newValue)
└── didMutate() [for storable nodes]Additional update methods:
didUpdateNode() — Manual update triggerdidUpdateNodeIfInitialized() — Only fires if hasDoneInit() is true, preventing spurious notifications during setupdidChangeSubnodeList() — Fired when the subnodes array changesA common pattern is to guard update logic so it only runs after initialization is complete:
didUpdateSlotFoo (oldValue, newValue) {
if (this.hasDoneInit()) {
this.didUpdateNode();
}
}