Closed jbeckton closed 8 years ago
Hi Jesse,
Thanks for your view. One of major benefits to adopt a mvvm framework is make more of your source code unit testable. it can be up till ViewModel layer when apply mvvm pattern correctly. As the software is getting more complicated, we want this capability.
Another benefit is assisting concerns and layer separation. You can have a read on 'project structure and best practices' if you have not - http://robobinding.github.io/RoboBinding/getting_started.html#_project_structure_and_best_practices, as well as Album Sample project and https://github.com/RoboBinding/Android-CleanArchitecture.
About the idea you described with UserInfo example, there is a problem. Your UserInfo has to be observable so that it can notify the changes to UI. You have either to dirty your UserInfo bean or you have to use some invasive way, for example XXObservable objects like AndroidBinding did in your ViewModels - https://github.com/gueei/AndroidBinding/blob/master/Demo/MarkupDemoICS/src/com/gueei/demos/markupDemo/viewModels/TextView.java.
In my opinion, views are better not to access entities directly, as views normally only access subset of entities' information and there could be some transformation. With a layer viewModel to isolate both sides, it is a good separation. with the text you gave 'bind:text="userInfoObj.Lastname"', it is actaully a method chaining anti-pattern, if you write it in java 'viewModel.userInfoObj.Lastname'. It means view knows about both viewModel and userInfo objects -https://en.wikipedia.org/wiki/Method_chaining.
The feature #164, which has not implemented, is a bit related. , https://github.com/RoboBinding/RoboBinding/issues/164
No further communications. Close it for now.
Just for the sake of posterity, https://github.com/Dellkan/robobinding-helpers set out to solve several of these issues. It does so by breaking a few patterns, and intentionally implementing a few anti-patterns.
It sits as a layer on top of Robobinding, and has (among others) the following features:
PresentationModelWrapper
gives you access to a method getData()
which then takes all annotated fields and puts them in a hashmap which you can easily put into a JsonObject for instance.@IncludeModel(prefix = "", excludefields = [""]) works in the following way:
@PresentationModel
public class MySubModel extends PresentationModelWrapper implements Serializable {
@Get
protected String title;
@Get
protected String image;
@GetSet
protected String customizableText;
@GetSet
protected String privateString;
}
@PresentationModel
public class MainModel extends PresentationModelWrapper implements Serializable {
@IncludeModel(prefix = "subModel", excludeFields = ("privateString"))
MySubModel myCustomSubModel;
@Get
protected String title;
}
The above enables the following types of layouts (Assume MainModel, and only MainModel is given to Robobinding)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://robobinding.org/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
src="{subModelImage}" />
<!-- This gives you title from MainModel -->
<TextView
bind:text="{title}" />
<!-- This gives you title from MySubModel -->
<TextView
bind:text="{subModelTitle}" />
<EditText
bind:text="${subModelCustomizableText}"
</LinearLayout>
@Dellkan Thanks. The intention on subModel is the same as #164 . We want a fine support for component-based development.
I will have a look your other parts when i get time next.
Thanks, Cheng
Just watched the video by Robert (2012) London Android User Group.
Early in the video Robert is showing the benefits of RoboBinding's MVVM by removing the "Crap" boilerplate code from the activity. Seems to me that RoboBinding has just moved the boilerplate code into the ViewModel. Looks like you are just trading the getViewByID in the activity to get a handle on each view for setters and getters in the ViewModel. I see other benefits to this library but for me it seems like there is still a good bit of boilerplate code to be written in order to get two way binding.
If I have a business layer that returns an object that has 10 properties then I have to write 20 functions (setters and getters) in my ViewModel so my ui can bind to it.
Is it possible to bind directly to the object instance?
in my ViewModel I have a property like:
UserInfo userInfoObj;
this property gets set by some service call that returns a single object.
then in my view xml:
bind:text="userInfoObj.Firstname"
bind:text="userInfoObj.Lastname"