doridori / Dynamo

A lightweight state-based controller for Android
186 stars 6 forks source link

How to handle callback from the DB layer #9

Open ido567 opened 9 years ago

ido567 commented 9 years ago

In my app I have 3 main layers:

I have a list with various items, and I want to delete one of them. Currently, the flow is:

My solution works, but I guess you have better idea of how to handle callbacks from the DB layer without dedicated state.

Thanks a lot!

doridori commented 9 years ago

Hey @ido567

A coupe of ideas spring to mind. Of course it depends on your use case - its interesting to see how you are alternating between a PendingState and a DeleteItemState, Im assuming at the mo that the Pending... is referring to a pending user-edit action?

Anyhow, the ideas I have initially fall into two camps

1) Updating the presentation layer that the loaded state has changed 2) Updating the presentation layer that an item has been deleted

These are similar but slightly different. For the sake of this example I will call the loaded data state LoadedState for clarity. In my mind the difference in the above to is regarding weather you actually need the UI to be aware of what items have been deleted? Sometimes when dealing with changing list data you just want the list to show only the items that are present in the backing data, whereas you may or may not want to show or animate deleted items out, which would require transmitted info to the UI about what elements have just been removed.

To achieve 1) you could just call setChanged and notifyObservers() from inside the Dynamo when the data has changed, which would result in the same state being passed to the UI, but with the updated data. In the UI this could result in the list being invalidated and therefore no longer showing the deleted data. If you were using your LoadedState observation to animate your ListView in you could now just check if its already Visible, and if so skipping the view switch & animation. Optionally your LoadedState could hold info about the last deleted item also, in case this is valuable to your use case.

For 2) You could use an EventBus event or state callback to just say "item ID x has been deleted" and use this into to custom animate / refresh your list etc. If you dont want to use an event bus you could optionally attach a custom UI callback to your LoadedState with an itemDeleted(int id) callback when theonState(LoadedState)method is called, and make sure this is removed inLoadedState.onExistingState()` method and / or when your UI is destroyed (depending on your Dynamo lifecycle choices)

As you can see these are pretty similar approaches, and I prefer approach no 1 I think. I wouldn't really want to use a separate ItemDeleted in most cases as feels more like an event than a state.

Let me know if this make sense and if you have any thoughts on it :)

ido567 commented 9 years ago

It seems like option 2 is more appropriate for me, because I need to animate item deletion. I feel that event bus is too complex for this issue, and maintain a callback pointer is not something which I will happily do.

Can't I send event to all the Observers?

doridori commented 9 years ago

Hi,

As Dynamos extend java.util.Observable you can only notify that the observed object has changed and not the nature of the change itself.

You could create a Dynamo with a custom Observer which could include any callback methods you want, but this is maybe overkill for this case. It is interesting however and it may make sense for Dynamo to implement a custom Observable<T extends Observer> class so you can easily add additional observable event methods to a single Dynamo. What do you think?

It may be simpler for your case to not worry so much about the callback if the delete action is coming from the UI itself anyway, i.e.

The callbacks are really only useful if the row deletion is happening from an external party also i.e. some data is deleted from a timer or some background process etc. You mention that the DB communication with different sources so unsure as the nature of your app in relation to this.

The UI-only approach makes more sense when i think about it as adding and removing UI animations require you to change the UI layer only, which is as it should be in most cases.

ido567 commented 9 years ago

You're right, the best solution is to animate the row out without waiting to the callback. Especially in this case when the data is removed from local DB.

Again, thanks a lot for the great library and for the support Looking for new versions with cool features