logoalt Hacker News

layer8yesterday at 8:39 AM1 replyview on HN

How do you handle UI state vs. underlying data (model) state, and dependencies between them? By UI state, I mean things like scrollbar position and selection state. When displaying a scrollable and selectable list of items, then for example when the number of items changes, the selection may need to adjust, and the scroll position may need to adjust. Depending on which items are added or removed (or reordered), the selection and scroll position may need to change differently for the apparent UI state to look stable for the user. If only the model is changed, a previous UI state like selection or scroll position may become invalid in relation to the new model state. Who updates the UI state accordingly to make it valid again? In the general case, application code needs to be involved in choosing the desired valid UI state when the underlying model state changes. How is the corresponding application code prevented from triggering further events?


Replies

mpweiheryesterday at 2:05 PM

>How do you handle UI state vs. underlying data (model) state, and dependencies between them?

I don't. And I don't have to, as I delegate that sort of stuff (mostly) to Cocoa/CocoaTouch etc.

https://blog.metaobject.com/2018/12/uis-are-not-pure-functio...

When you have stateful view objects, these stateful view objects maintain the view state. When updating themselves with new data due to a ModelDidChange notification, they take care of reconciling their current display state with the underlying model state.

> When displaying a scrollable and selectable list of items

So for example an NSTableView or NSCollectionView. I personally use a subclass that interacts directly with a table representation, meaning a lot of the glue code that Cocoa(Touch) requires disappears.

> Who updates the UI state accordingly to make it valid again?

Always the view. Who else?

> In the general case, application code needs to be involved in choosing the desired valid UI state when the underlying model state changes.

How so? The view is always a reflection of the model data. Whether that is a "change" is actually mostly irrelevant, even though the notification is called ModelDidChange in my case. In Smalltalk MVC it is the #changed message. It means "you are out of date, please make yourself reflect the model".

This same mechanism also handles the model being changed by some other party without any further code. "The model has changed, please update yourself to reflect the current state of the model". That's it, modulo optimizations.

> How is the corresponding application code prevented from triggering further events?

Model code isn't involved. A ModelDidChange event is only triggered when...er...the model changes.

That said nothing prevents you from manually invoking the ModelDidChange notification, just like nothing prevents you from calling abort(), running an infinite loop, creating an unbounded recursion or reading from /dev/random until it is exhausted ...

Doing it by accident, though, is very hard, because it just isn't part of the programming model.