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

More UI coding conventions #753

Merged
merged 5 commits into from
Nov 7, 2023
Merged

Conversation

erri120
Copy link
Member

@erri120 erri120 commented Nov 6, 2023

  • Adds more context to OAPH
  • Adds a section about design view models
@erri120 erri120 added Documentation This is related to our documentation. Design UI/UX This is related to the UI. labels Nov 6, 2023
@erri120 erri120 requested a review from a team November 6, 2023 14:24
@erri120 erri120 self-assigned this Nov 6, 2023
docs/UICodingConventions.md Outdated Show resolved Hide resolved
}
```

If a view model creates other view models, those view models **should** not be design view models. Don't try and get fancy with factory methods and other unnecessary abstractions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if a Design VM has properties containing other VMs, that require passing stuff in the constructor, can I just instantiate the Design version of the child VMs instead since we are already in a design VM?

This would avoid having to create mock data for the non design version in the parent DesignVM, on top of having to create that mock data already in the child DesignVM

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As stated above, the design view model should only set up data. The normal VM would then take that data and create other VMs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can check the FOMOD changes I recently did. I massively cleaned up the design VMs: https://github.com/Nexus-Mods/NexusMods.App/pull/738/files#diff-9867405e9fbd8549cf89ffca330cee4eef1c8a421dba0cb637e5e5b36f59d897

Copy link
Contributor

@Al12rs Al12rs Nov 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then you end up in a situation where if a standard VM has a constructor with custom parameters, you need to fabricate mock version of that data twice, once in the DesignVM to allow for a constructor without arguments, and then again in any parent DesignVM that needs to instantiate the standard VM.

This would then call for getting "fancy" to generate that data to avoid ending up with replicated code.

Is there a specific reason why we should not instantiate child designVMs inside designVMs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the parent has a list of children, you can make a data generation method on the child and re-use it in the parent.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to avoid a case where the design view model and the normal view model do the same thing by instantiating child view models, but the difference is in the type. This was an issue with the previous FOMOD code, where I'd had duplicate code that did the same thing but with a different type.

Copy link
Contributor

@Al12rs Al12rs Nov 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if the alternative is

// inside a DesignVM constructor
ChildVM = new ChildVM(ChildDesignVM.GenerateDummyData());

Is it really any better than just:

// inside a DesignVM constructor
ChildVM = new ChildDesignVM();

Assuming ChildDesignVM extends ChildVM.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that scenario there isn't much difference. My concern mainly lies with collection of child view models, since you usually construct those by connecting to a SourceCache:

//MyViewModel:
_sourceCache
  .Connect()
  .Transform(data => new ChildViewModel(data))
  .BindTo(out _children);

If you'd want to create a MyDesignViewModel and you have a ChildDesignViewModel, then you should not copy this code and change the Transform call to create a ChildDesignViewModel instead of a ChildViewModel. The ideal solution would be to just create dummy data in the MyDesignViewModel and let the base class MyViewModel create instances of ChildViewModel using that dummy data, similar to how a ChildDesignViewModel uses dummy data to pass it to the base constructor of ChildViewModel.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, so the general idea is to reduce as much as possible the changes in logic between MyVM and MyDesignVM.
I guess the example you posted above then is a better one to illustrate the point the documentation is trying to make.
If possible the DesignVM should just generate dummy data and feed it to the base VM.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update the docs to be more precise.

Copy link

codecov bot commented Nov 7, 2023

Codecov Report

Merging #753 (4d403f4) into main (b324e46) will increase coverage by 0.03%.
Report is 2 commits behind head on main.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #753      +/-   ##
==========================================
+ Coverage   62.73%   62.76%   +0.03%     
==========================================
  Files         585      585              
  Lines       17422    17420       -2     
  Branches     1219     1219              
==========================================
+ Hits        10930    10934       +4     
+ Misses       6170     6169       -1     
+ Partials      322      317       -5     
Flag Coverage Δ
Linux 61.91% <0.00%> (-0.06%) ⬇️
Windows 61.88% <0.00%> (-0.01%) ⬇️
clean_environment_tests 62.74% <0.00%> (+0.02%) ⬆️
network_tests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
src/NexusMods.App.UI/ReactiveUIExtensions.cs 61.22% <0.00%> (-4.00%) ⬇️

... and 3 files with indirect coverage changes

@erri120 erri120 requested a review from Al12rs November 7, 2023 11:07
@erri120 erri120 merged commit 9182f89 into Nexus-Mods:main Nov 7, 2023
5 checks passed
@erri120 erri120 deleted the issue-737-ui-docs-2 branch November 7, 2023 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design UI/UX This is related to the UI. Documentation This is related to our documentation.
2 participants