Change Tracking View Model: When/How to "Start Tracking"? [closed] - silverlight

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have need of a view model that tracks changes so the user can see things visually change in response to edits and rollback portions. Right now, I "turn on" change tracking as the last step in the constructor for the view model (necessary, because sometimes the view models are constructed from templates or have defaulting logic that triggers PropertyChanged before construction is complete, erroneously leading one to think it's changed even before the user has done anything).
This has worked for the most part,
but with more complicated controls, bindings, and lack of controlling the order for various events in third-party products
and, a need to turn on change tracking after view model is built from a DTO returned from a service call (i.e. the model-model),
is there a better place to turn-on change tracking?

In an ideal MVVM implementation there's neither better nor alternative place, because you aren't likely to know when or how a view communicates with a view model. In fact, a view model shouldn't know anything about a view. A view might be a Silverlight UI or a console app, or a test mock-up, or whatever else. According to general thoughts then, constructor seems to be the only place where 'change tracking' should be disabled.
If you try following the MVVM strictly, you should accept your view models as main objects and views as secondary ones. I mean a view shouldn't introduce any logic that doesn't relate to the specific view implementation. It only displays the current view model state and communicates a user's actions to the view model. If it's true, then you won't need to turn change tracking off wherever except the constructor.
Of course, in the real world this might get rather difficult to follow. If you can't find another solution, you could introduce additional properties to the view model, e.g. IsViewInitialized, which would turn on 'change tracking', and make the view set the property as required.
But you'd better avoid this as long as possible. Such an approach increases coupling between Views and ViewModels which is against one of the main ideas of the MVVM pattern.
If you'd ask me in personal, my view models quite rarely have an alternative logic for the initialization steps and if they do, it's only in the constructors. And I usually don't 'turn off change tracking' but rather set some fields directly to get around the regular change tracking code that for most cases resides in property setters. But sometimes it's more convinient to trigger that logic for some properties even in a constructor.

Generally, there is no "right" or "wrong" place to handle change tracking.
But if you prefer to do it inside VM, your RaisePropertyChanged() method can accumulate list of changed properties (changesList). You should implement public (possibly virtual) method ApplyChanges(), that clears this list and saves data (if you post changes through network, add more checks so you don't send the same data over and over). Also, have public property bool IsChanged { get; }, that returns changesList.Any() -- you can use this property to bind your "Apply" buttons to.
For your case: in complex constructors, invoke ApplyChanges() to reset IsChanged state, and after complex controls are bound to your VM, also invoke ApplyChanges() - even if you know user didnt do anything yet.

Related

Conditional logic vs duplication in MVVM [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
We have a module with its Views, ViewModels and Models and a requirement came in to have an exact copy of the module, but part of the functionality has to be read-only.
The read-only mode should be turned on by a configuration parameter. The Model part is the same - it will use the same data sources.
I see two possible solutions to this problem:
Change the existing Views and ViewModels, by manipulating controls' interactivity based on the param.
Downsides of this approach is additional conditional logic. We're worried that if we do this, another requirement might come in, where we have to add more conditional logic. Upside - no duplication.
Another way is to split the existing view's into multiple components and assemble the regular module version and the read-only version using those components. We could disable interactivity on the View level in read-only versions and inherit from the ViewModel of the View which we're splitting from and override needed behaviour. The upside would be modularity. Downside - duplication, multiple places to maintain when new components are added in the future.
What's the preferred approach to solve problems like this?
This is a little simpler than you think.
The most elegant approach is to have a flag or value contained within the viewmodel which represents the editable state of the data (this could simply be a true/false flag, but I've also seen cases where it can be represented as an enum because there are multiple conditions or states).
Then within the view you can bind the control's IsEnabled or IsReadOnly properties to that value (using a converter if necessary to change the value to a boolean).
Obviously impossible to give a definitive answer without knowing all the specifics, but I generally take the view that if something is only required once, or maybe even twice, then I'll take the quickest and easiest route. In your case that would be to add conditional logic to the existing classes.
At the third change, I'll review and see if it needs to be split out into a separate entity. but more often than not the third (or even second) change never comes. Don't code for the future, YAGNI.

How much view-agnostic is a ViewModel supposed to be in MVVM?

Let's imagine a very simple UI, where there's a list of checkboxes. When you click on any of them:
1) if it's not selected, it should create a workspace with this checkbox name (and more logic then is available in that workspace, but that's irrelevant to the question). The checkbox naturally then becomes selected;
2) If it's already selected, it should turn unselected and should destroy the associated workspace.
The straightaway form of implementing this is to have the View look at the state of the clicked checkbox and depending on being already selected or not do a viewModel.createWorkpace() or viewModel.destroyWorkspace(). But then that means that this logic is in the View -- I get the impression it'd be better to have it in the ViewModel.
I've read that the ViewModel for diverse reasons should not know the View. But one thing is not having a physical dependency to the View (an object reference, for instance) and another completely different is not even being aware that the View may have checkboxes, as in this example.
It gives me the impression that actually there's really not big of a point in making the View and ViewModel that much different, and in fact, the closer the ViewModel is to the View, the easier it is to bind data between the View and ViewModel.
How should I deal with this situation and why?
Thanks
The idea is to decouple the view and viewmodel.
You should be able to instantiate the viewmodel separately.
The primary reason for this is not some vague neatness or something.
The primary reason is so you can easily exercise tests on your code by instantiating a discrete class.
The view should do view things which are related to displaying data and allowing the user to interact.
The viewmodel should have the code that acts on those interactions and presents data to the view.
This does not mean the view should have no code at all.
If there is code, however, it should be view specific.
It's a good idea to use re-usable code such as behaviours.
Because then you can manually test these and prove they work. Then re-use your proven code.
Similarly with converters, validators etc.
All code.
All used in views.
I suppose it is theoretically possible to write an app which has no converters or validators or behaviours. I've never seen a serious business app didn't have all three though.
It is less important that the view knows nothing about the viewmodel than the reverse.
You're not going to instantiate the view to exercise tests unless you also have a viewmodel instantiated for it.
That doesn't mean you should just bung all your code into code behind though.
Why is that exactly?
Because the god of MVVM will strike you down with his lightning bolts?
Nope.
Because this will make future development easier?
Well it might, but not usually so much you'd notice.
Why then?
Because instantiating a view with it's controls is very slow.
They unavoidably have a lot of dependencies you can't mock.
It is likely to depend on resource in the application, so you'd have to instantiate an application and merge resource dictionaries.
Views often depend on swathes of libraries, pictures, usercontrols etc etc.
None of which you can mock.
So you need everything.
By the time you automate instantiating everything in some test runner and iron out clicking on buttons etc...
Your head will be hurting and you'll find those 2000 test you're theoretically wanting to run in a couple of seconds every 10 minutes take much longer than that couple of seconds.
You can't do "proper" TDD if you instantiate views in tests.
To answer your workspace checkbox question.
It depends on what a workspace is really.
A common pattern would be to initiate code in the setter of a viewmodel property bound to the ischecked property of each checkbox.
That might be in a viewmodel presented per checkbox which had the name of the workspace, it's type or whatever is required to do it's check-uncheck stuff.
Each would hold some sort of reference to these things it's creating so it can dispose them or whatever when that ischecked value becomes false.

WPF MVVM using LINQ to SQL

I have binded my customer name textbox to Customer Model and set the mode to two way now I want to update the edited name to database. How can I achieve this ?
Your question is very vague as it doesn't say whether you wanted this on PropertyChanged or when you have a button with either Click event handling or ICommand binding on it.
The decision when to update is totally down to the business model that you are applying. Generally speaking, it's never a good idea to update directly from a PropertyChanged event because it might be a temporary edit and you may wish to update against.
For example, if you have UpdateSourceTrigger=PropertyChanged, then as soon as a character is type, the Property is updated with the new value and if you implmented iNotifyPropertyChanged events, that would instantly fire an update to your database. Because a database connection is transient, usually over a network, it may or may not be available, and it may or may not timeout during a partial update. Thus, you could end up locking up your code or if multi-threading, causing race conditions.
Therefore, it's always better to implement the changes via a save button or when the screen is closed/navigated away from (such as what iOS/Android do).

Accessing ViewModel data in View

I just want to ask if it's OK to access the ViewModel's data in the View backend?
Basically I just need a check to see if a ViewModel's property is set (which gets set when the user selects something), and if it's not I'll just redirect the user to another View telling him he needs to select something first. Is this a poor-design practice or is it OK, just for a minor check like this? Really don't want to implement a static class and extrapolate the data to it, and check it instead.
Another question tightly related to this, is can I call a method from the View (when the View is closing), that unregisters that particular ViewModel from the IoC container (this ViewModel isn't singleton). The alternative is to send a message from the View to the ViewModel when the View is closing, and when the ViewModel gets that message it unregisters itself. The problem I'm trying to solve with this is that, every time that ViewModel is requested it has to be a new one, but my IoC container caches them, making my program a memory hog. All of the ViewModels get released on application exit, meaning x ViewModels will still exist in the cache even though they're most likely not needed.
Basically I just need a check to see if a ViewModel's property is set (which gets set when the user selects something), and if it's not I'll just redirect the user to another View telling him he needs to select something first. Is this a poor-design practice or is it OK, just for a minor check like this?
It does not seem to be wrong to check the value of some ViewModel property and reflect the changes on the View side. The View state could be "bound" to the ViewModel state by the WPF data binding mechanism: Binding, Triggers (Trigger, DataTrigger, EventTrigger), Commands (including EventToCommand), etc.
But sometimes it is useful to handle ViewModel state change by the ViewModel itself using UI Services. For example, IWindowService interface can be introduced to allow to open windows from the context of the ViewModel implementation.
Another question tightly related to this, is can I call a method from the View (when the View is closing), that unregisters that particular ViewModel from the IoC container (this ViewModel isn't singleton).
...
The problem I'm trying to solve with this is that, every time that ViewModel is requested it has to be a new one, but my IoC container caches them, making my program a memory hog. All of the ViewModels get released on application exit, meaning x ViewModels will still exist in the cache even though they're most likely not needed.
It seems to be strange that the described dependency container "cache effect" exists when the registration is specified as "resolve per call behavior" (not "singleton behavior"). Please check that the registration is specified as "resolve per call behavior" (for example, PerResolveLifetimeManager in terms of Unity Container Lifetime Managers).
Update
The ViewModel lifetime problem exists because SimpleIoC container is used.
I would like to recommend using another dependency injection container (with appropriate lifetime management) to make the implementation less complex and error-prone.
But, if there is a strong need to use SimpleIoC container, some kind of the ViewModel lifetime management can be implemented using:
SimpleIoc.Default.GetInstance<ViewModel>(key); method call to resolve an instance of ViewModel;
SimpleIoc.Default.Unregister(key); to un-register the instance when it is no longer needed (Closed event, etc).
The implementation can be found here: answer #1, answer #2.

reference on backbone updating views, always based on state-change or as eventhandler side-effect?

Pretty cryptic question I admit.
I'm looking for references / best practice in updating views based on a GUI event.
Basically I'm seeing 2 different ways to do this:
every view-change is a reaction to a model-change
Gui event
viewhandler (custom or 2-way binding lib) that
updates Model based on view
the View has a listenTo defined on the MOdel that was updated, which gets invoked
do whatever DOM-changes we want
Do DOM-changes directly in the viewhandler
Gui event
viewhandler (custom or 2-way binding lib) that
updates Model based on view
do whatever DOM-changes we want
the View has a listenTo defined on the MOdel that was updated, which gets invoked
The fist approach seems the most clean to me: it can use validation rules on the model, before changing the DOM and the flow just feels better. However, I can't find any good references to back this up. What is generally considered best practice here?
I wouldn't know what is Overall Internet Agreement on that topic, but working on a fairly large Backbone application with complex views, the first approach is what has proven the most maintainable.
One way to see it is that as you know, Backbone's Views and Backbone's Routers are kinda sharing the workload of what would be an actual Controller in a standard MVC (say, Rails). What that means is that in a view, you'll typically have the logic to translate GUI events (click on X) to Model Change (do Y) and the logic to translate Model Changes (new state after Y) into DOM changes. That doesn't mean the logic needs to be in the same place, those are two separate things. Your model may be shared among multiple views and you need your View to react regardless of where the change is originating. You could also be waiting for the server to answer whatever, and so, the DOM update would be in a callback anyway.
A pattern I have been using a lot lately is to have a _renderUpdating() to update the DOM to let the user know that his action has been taking into account (add a spinner near to whatever triggered the change), but I let events do the actual re-rendering once the server has returned the new model.
There is nothing that prevents you from going with the 2nd approach in simple cases, but as your application grow, you'll be very happy to have more than just a single render() that erases everything (including subviews) and you'll be looking at having a clean break between view -> model (which is the role of a controller) and model -> view to allow for more flexibility.

Resources