diff --git a/src/Fabulous.Tests/APISketchTests/TestUI.Widgets.fs b/src/Fabulous.Tests/APISketchTests/TestUI.Widgets.fs index 6758d30ec..beece0527 100644 --- a/src/Fabulous.Tests/APISketchTests/TestUI.Widgets.fs +++ b/src/Fabulous.Tests/APISketchTests/TestUI.Widgets.fs @@ -47,7 +47,8 @@ module TestUI_Widgets = let oldWidget: Widget voption = ValueNone Reconciler.update context.CanReuseView oldWidget widget viewNode - struct (viewNode :> IViewNode, box view) } + struct (viewNode :> IViewNode, box view) + AttachView = fun (_widget, _context, _parentNode, _view) -> failwith "not implemented" } WidgetDefinitionStore.set key definition key diff --git a/src/Fabulous/Memo.fs b/src/Fabulous/Memo.fs index fa1dae2c1..f961a82dd 100644 --- a/src/Fabulous/Memo.fs +++ b/src/Fabulous/Memo.fs @@ -88,6 +88,7 @@ module Memo = // store widget that was used to produce this node // to pass it to reconciler later on node.MemoizedWidget <- Some memoizedWidget - struct (node, view) } + struct (node, view) + AttachView = fun (_widget, _context, _parentNode, _view) -> failwith "Memo widget cannot be attached" } WidgetDefinitionStore.set MemoWidgetKey widgetDefinition diff --git a/src/Fabulous/Runners.fs b/src/Fabulous/Runners.fs index c7b048955..c5f0a72d8 100644 --- a/src/Fabulous/Runners.fs +++ b/src/Fabulous/Runners.fs @@ -36,6 +36,8 @@ type IViewAdapter = inherit IDisposable /// Instantiates a new view using the current state associated with this ViewAdapter abstract CreateView: unit -> obj + /// Attaches to the existing view and updates it with the current state associated with this ViewAdapter + abstract Attach: obj -> unit module RunnerStore = let private _runners = Dictionary() @@ -183,6 +185,24 @@ module ViewAdapters = _root <- root _root + member _.Attach(root) = + let state = unbox(StateStore.get stateKey) + let widget = (view state).Compile() + _widget <- widget + + let treeContext = + { CanReuseView = canReuseView + GetViewNode = getViewNode + Logger = logger + Dispatch = this.Dispatch } + + let definition = WidgetDefinitionStore.get widget.Key + + let _node = + definition.AttachView(widget, treeContext, ValueNone, root) + + _root <- root + /// Listens for StateStore changes and updates the view if necessary member _.OnStateChanged(args) = try @@ -211,6 +231,7 @@ module ViewAdapters = interface IViewAdapter with member x.Dispose() = x.Dispose() member x.CreateView() = x.CreateView() + member x.Attach(root) = x.Attach(root) /// Create a new ViewAdapter for the component let create<'arg, 'model, 'msg, 'marker> diff --git a/src/Fabulous/WidgetDefinitions.fs b/src/Fabulous/WidgetDefinitions.fs index afc3f4b3c..cb93ac44a 100644 --- a/src/Fabulous/WidgetDefinitions.fs +++ b/src/Fabulous/WidgetDefinitions.fs @@ -9,7 +9,8 @@ type WidgetDefinition = { Key: WidgetKey Name: string TargetType: Type - CreateView: Widget * ViewTreeContext * IViewNode voption -> struct (IViewNode * obj) } + CreateView: Widget * ViewTreeContext * IViewNode voption -> struct (IViewNode * obj) + AttachView: Widget * ViewTreeContext * IViewNode voption * obj -> IViewNode } module WidgetDefinitionStore = let private _widgets = ResizeArray()