These are chat archives for ractivejs/ractive

12th
Jun 2017
Matt Granmoe
@granmoe
Jun 12 2017 18:15

noob question: I've seen code like this:

        clearCompleted: function () {
            var items = this.get('items');
            var i = items.length;

            while (i--) {
                if (items[i].completed) {
                    items.splice(i, 1);
                }
            }
        },

Where grabbing and then altering any property of a ractive's data from anywhere anyhow automatically keeps everything in sync. How does this work? Is it just using normal references so that you are just altering the same instance? I.e. the items up there is always the same array instance until we explicitly set the value of items to some new array instance? Maybe these questions don't make sense. I'm coming from using react/redux for a while, so this all seems like the wild west in terms of state management. Any caveats with this level of freedom/flexibility?

I guess maybe it looks weird to me because you are implicitly altering the same instance as opposed to calling some method formally like this.set('foo', 123)
kouts
@kouts
Jun 12 2017 18:17
I usually do: var items = this.get('items').splice(); just to be sure I'm not altering the data model
then I'm setting the array at once
Matt Granmoe
@granmoe
Jun 12 2017 18:17
oh, right. Like if you wanted to use the data but not necessarily modify it immediately
right, in the example I shared, they are invoking multiple mutations of the data
I like that approach better. Does anyone use anything like immutable.js in the ractive world?
kouts
@kouts
Jun 12 2017 18:18
I'm not sure if this behavior has changed in 0.9 though
if this is some "magic" thing that Ractive does, maybe it's removed in 0.9
which version are you using?
Joseph
@fskreuz
Jun 12 2017 18:19
iirc, items will be the same array as in the data. ractive.get doesn't defensively clone objects. Mutating it will mutate the array in the data.
Matt Granmoe
@granmoe
Jun 12 2017 18:20
in a few examples I've seen, the code is relying on the fact that it is the same instance
Joseph
@fskreuz
Jun 12 2017 18:21
Doing ractive.set('items', somethingElse) will replace the data.
kouts
@kouts
Jun 12 2017 18:21
So @grnmoe in your example if the items array is inside a template this will alter the DOM as well, right?
Matt Granmoe
@granmoe
Jun 12 2017 18:22
yeah, I'd assume so
data in, template out
kouts
@kouts
Jun 12 2017 18:23
This always confuses me, that's why if I have to deal with an array in JS world (i.e not inside the template) I will clone it first
Matt Granmoe
@granmoe
Jun 12 2017 18:24
this is a big difference between ractive and react/redux: in the latter, any time you change the app state you have to go all the way to the top (the "reducer") by firing an action which will then create a new state tree for the whole app. In ractive, it seems like you can alter data anywhere anyhow and store it amongst your components however you want.
far less plumbing on the ractive side from what I've seen so far
@kouts you might like working with an immutable data library then. Immutable.js is great, though it's so robust that you can really lose yourself in the docs.
Joseph
@fskreuz
Jun 12 2017 18:26
You can think of Ractive as being similar to Angular, two-way enabled by default. It can be disabled by setting twoway:false, if you want to go the React+Redux route.
Matt Granmoe
@granmoe
Jun 12 2017 18:26
:thumbsup:
Chris Reeves
@evs-chris
Jun 12 2017 18:31
the array is the same array as is in the data, but ractive won't know about the changes until you tell it
you can do that with ractive.update('items')
Matt Granmoe
@granmoe
Jun 12 2017 18:32
oh weird...I wonder how this example works then? https://github.com/tastejs/todomvc/blob/gh-pages/examples/ractive/js/app.js
Chris Reeves
@evs-chris
Jun 12 2017 18:32
or if you want shuffle-y behavior ractive.set('items', items, { shuffle: true })
it's out of date :smile:
there was an array adaptor that automatically replaced splice and friends on any arrays added to ractive data
it has since been turned off by default (0.8) and removed (0.9) because it caused confusion and performance degradation
Matt Granmoe
@granmoe
Jun 12 2017 18:33
oh I see...wow, glad I asked then. Thanks :)
Chris Reeves
@evs-chris
Jun 12 2017 18:36
for the record, the modern equivalent is
var items = this.get('items'), i = items.length;
while (i--) {
  if (items[i].completed) this.splice('items', i, 1);
}
it just moves the data manipulation to a path through ractive so it knows what to update
Matt Granmoe
@granmoe
Jun 12 2017 18:38
:thumbsup:
Does it batch updates somehow? Or does each call to this.splice cause an update?
Chris Reeves
@evs-chris
Jun 12 2017 18:39
each splice will cause an update
you can avoid that by modifying the array outside of ractive and then using the shuffle set
this is one of the things we're working to improve for 1.0
Matt Granmoe
@granmoe
Jun 12 2017 18:41
can I just build a new array and then call this.set('items', totallyNewArrayInstance) once at the end?
and will that automatically cause a render if things are different?
Chris Reeves
@evs-chris
Jun 12 2017 18:41
you can
you can also ractive.update('items')
Matt Granmoe
@granmoe
Jun 12 2017 18:41
if the data is the same even though the array instance is new, is ractive smart enough to not update the DOM?
Chris Reeves
@evs-chris
Jun 12 2017 18:42
which just says, "hey this changed, so poke through an update what you need to"
yes, it won't update dom it doesn't need to
Matt Granmoe
@granmoe
Jun 12 2017 18:42
:thumbsup:
Chris Reeves
@evs-chris
Jun 12 2017 18:42
but if you have transitions somewhere it will get weird
that's what the shuffle is for
basically keyed vs non-keyed updates from other libraries
Matt Granmoe
@granmoe
Jun 12 2017 18:44
so err on the side of modifying the same array instance when possible instead of replacing it entirely?
Chris Reeves
@evs-chris
Jun 12 2017 18:48
if you want keyed updates for a batch of changes, use ractive.set('items', items, { shuffle: true }), where items can be the same array or a modified clone
if you want a keyed update for a single change (which can remove and add many records, just at the same point in the array), use ractive.splice('items', remove, ...add)
if you don't care about keyed-ness, you can ractive.set('items', items) or ractive.update('items'), which, in practice, tends to be the fastest but will shift all of the data up and remove any records from the end of the iterative section
I usually just do the ractive.update('items') path because I rarely use transitions for lists large enough that individual splices would hurt performance
Matt Granmoe
@granmoe
Jun 12 2017 18:54
good info, thanks
Does "keyed-ness" refer to ractive being able to identify (by key) that an item in a template has moved position due to insertion/removal of some other item in an array?
Like to keep track of what DOM nodes need to be removed/inserted and which ones can stay the same?
Chris Reeves
@evs-chris
Jun 12 2017 18:55
yes
keyed updates associate a chunk of dom with a particular item in the array
non-keyed updates associate a chunk of dom with an index in the array
Matt Granmoe
@granmoe
Jun 12 2017 18:56
oh I see