https://kotlinlang.org logo
#kvision
Title
# kvision
i

Ilya Tel

01/28/2023, 4:13 PM
Hello, I have a few questions. 1. what are the use cases for
refreshOnUpdate
? I read the documentation and saw only `override fun buildClassSet(classSetBuilder: ClassSetBuilder)`use case. For example, сan it interact with rendering ? (not working):
Copy code
class Example(ids: List<Long>): SimplePanel() {
    var myIds by refreshOnUpdate(ids)
    init {
        button("${myIds}") {//interact somehow
            onClickLaunch { myIds = listOf(2L) }
        }
    }
}
2. What if I have a component where models comes as an argument
models: ObservableValue<List<Order>>
. Inside I create
val pagination: ObservableValue<Pagination>
Next, I want to have a
div
that will change when the
models
changes or when the
pagination
changes. I can't figure out how to achieve this now. For example, I can't put models and pagination in
val state: ObservableValue<SomeState>
because
models
are being updated in another component, but the rerender will only happen when the
state
changes
state.setValue(state.value.apply{})
r

Robert Jaros

01/28/2023, 4:40 PM
refreshOnUpdate
delegate lets you easily declare properties, which change how the component should be rendered (what element is rendered and what attributes, classes and styles are applied to it). When used, it will re-render the component when the value is set. In general you don't need to use refreshOnUpdate, unless you are implementing some kind of advanced component.
In your example there is no point using refreshOnUpdate, because your component doesn't change when
myIds
variable changes. It's child component does (but the init {} block is not called on re-rendering).
You should rather use this code to explicitly modify child component:
Copy code
class Example(ids: List<Long>): SimplePanel() {
    var myIds = ids
        set(value) {
            field = value
            button.text = "$value"
        }

    private val button: Button
    init {
        button = button("$ids") {//interact somehow
            onClick { myIds = listOf(2L) }
        }
    }
}
i

Ilya Tel

01/28/2023, 4:53 PM
Oh well, I think I get it. what about the second question ? At the moment, I'm a little confused because I don't know how to bind a component to several different
ObservableValue
r

Robert Jaros

01/28/2023, 4:55 PM
Use
RefreshOnUpdate
when you are overrding methods like
render
,
buildClassSet
,
buildAttributesSet
,
childrenVNodes
,
As for the second question - you can't.
You should join these observables into a single one.
i

Ilya Tel

01/28/2023, 4:58 PM
ok thanks for the help
r

Robert Jaros

01/28/2023, 5:01 PM
You don't need to use only a single one observable for everything (like some kind of strict single source of truth principle). But you should divide your state into rather independent parts.
If you want to be sure some components won't be unnecessarily refreshed, you can bind to a part of your state using
bind
with a
sub
parameter.
It will create an internal sub-observable, that will change only when selected part of the main state changes
i

Ilya Tel

01/28/2023, 5:05 PM
As far as I understand, in KVision it is not very convenient to update a multi-level store, and a multi-level store is not what should be used in KVision
r

Robert Jaros

01/28/2023, 5:07 PM
You mean observables inside other observables?
i

Ilya Tel

01/28/2023, 5:10 PM
No, I mean one single ObservableValue that would serve as a tiered storage. What about observables inside other observables ? doesn't that look pointless ?
r

Robert Jaros

01/28/2023, 5:10 PM
Yes, observables inside observables are bad 🙂
The state should be immutable
If you want more convenient method to work with more complex state, you can try using copykat (https://github.com/kopykat-kt/kopykat). Haven't tried this myself but it looks nice.
22 Views