Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Model from helper #549

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions src/Elmish.WPF/DynamicViewModel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ module internal IViewModel =
type internal ViewModelHelper<'model, 'msg> =
{ GetSender: unit -> obj
LoggingArgs: LoggingViewModelArgs
Model: 'model
Bindings: IReadOnlyDictionary<string, VmBinding<'model, 'msg, obj>>
ValidationErrors: IReadOnlyDictionary<string, string list ref>
PropertyChanged: Event<PropertyChangedEventHandler, PropertyChangedEventArgs>
Expand Down Expand Up @@ -70,19 +69,18 @@ module internal ViewModelHelper =
let create getSender args bindings validationErrors ={
GetSender = getSender
LoggingArgs = args.loggingArgs
Model = args.initialModel
ValidationErrors = validationErrors
Bindings = bindings
PropertyChanged = Event<PropertyChangedEventHandler, PropertyChangedEventArgs>()
ErrorsChanged = DelegateEvent<EventHandler<DataErrorsChangedEventArgs>>()
}

let getEventsToRaise newModel helper =
let getEventsToRaise helper oldModel newModel =
helper.Bindings
|> Seq.collect (fun (Kvp (name, binding)) -> Update(helper.LoggingArgs, name).Recursive(helper.Model, newModel, binding))
|> Seq.collect (fun (Kvp (name, binding)) -> Update(helper.LoggingArgs, name).Recursive(oldModel, newModel, binding))
|> Seq.toList

let raiseEvents eventsToRaise helper =
let raiseEvents helper eventsToRaise =
let {
log = log
nameChain = nameChain } = helper.LoggingArgs
Expand Down Expand Up @@ -117,6 +115,8 @@ type [<AllowNullLiteral>] internal DynamicViewModel<'model, 'msg>
nameChain = nameChain
} = loggingArgs

let mutable currentModel = args.initialModel

let (bindings, validationErrors) =
let getFunctionsForSubModelSelectedItem initializedBindings (name: string) =
initializedBindings
Expand All @@ -132,7 +132,7 @@ type [<AllowNullLiteral>] internal DynamicViewModel<'model, 'msg>

let initializeBinding initializedBindings binding =
Initialize(loggingArgs, binding.Name, getFunctionsForSubModelSelectedItem initializedBindings)
.Recursive(initialModel, dispatch, (fun () -> this |> IViewModel.currentModel), binding.Data)
.Recursive(initialModel, dispatch, (fun () -> currentModel), binding.Data)

log.LogTrace("[{BindingNameChain}] Initializing bindings", nameChain)

Expand All @@ -156,20 +156,21 @@ type [<AllowNullLiteral>] internal DynamicViewModel<'model, 'msg>
(bindingDict :> IReadOnlyDictionary<_,_>,
validationDict :> IReadOnlyDictionary<_,_>)

let mutable helper =
let helper =
ViewModelHelper.create
(fun () -> this)
args
bindings
validationErrors

interface IViewModel<'model, 'msg> with
member _.CurrentModel : 'model = helper.Model
member _.CurrentModel : 'model = currentModel

member _.UpdateModel (newModel: 'model) : unit =
let eventsToRaise = ViewModelHelper.getEventsToRaise newModel helper
helper <- { helper with Model = newModel }
ViewModelHelper.raiseEvents eventsToRaise helper
let oldModel = currentModel
currentModel <- newModel
ViewModelHelper.getEventsToRaise helper oldModel newModel
|> ViewModelHelper.raiseEvents helper

override _.TryGetMember (binder, result) =
log.LogTrace("[{BindingNameChain}] TryGetMember {BindingName}", nameChain, binder.Name)
Expand All @@ -179,7 +180,7 @@ type [<AllowNullLiteral>] internal DynamicViewModel<'model, 'msg>
false
| true, binding ->
try
match Get(nameChain).Recursive(helper.Model, binding) with
match Get(nameChain).Recursive(currentModel, binding) with
| Ok v ->
result <- v
true
Expand All @@ -201,7 +202,7 @@ type [<AllowNullLiteral>] internal DynamicViewModel<'model, 'msg>
false
| true, binding ->
try
let success = Set(value).Recursive(helper.Model, binding)
let success = Set(value).Recursive(currentModel, binding)
if not success then
log.LogError("[{BindingNameChain}] TrySetMember FAILED: Binding {BindingName} is read-only", nameChain, binder.Name)
success
Expand Down