updating ractive.js when array changes without 'magic: true'

250 Views Asked by At

I use Ractive to display data from a constantly changing array (received from PouchDB) with the magic: trueparameter. That worked fine until in Version 0.9.x this parameter was no longer available.

So it is advised to use ractive.update()every time my array changes. The problem I'm facing seems quite simple, but I'm fairly inexperienced: For tracking the changes I do roughly the following (taken from a PouchDB script):

fetchInitialDocs().then(renderDocsSomehow).then(reactToChanges).catch(console.log.bind(console));

function renderDocsSomehow() {
    let myRactive = new Ractive({
      el: '#myDiv',
      template: 'my Template',
      //magic: true,
      data:{
        doc1: docs
      },
      components: {myComponents},
      computed: {computedValues}
    });
}
function reactToChanges() {
    //here my changes appear
    onUpdatedOrInserted(change.doc);
    myRactive.update() // <- I cannot use update here because "myRactive" is not known at this point.
}

What I tried also was setting an observer in the renderDocsSomehow() function

ractive.observe('doc1', function(newValue, oldValue, keypath) {
  ractive.update()
});

but this did not do the trick.

So how can I inform Ractive that my data has changed and it needs to update itself?

3

There are 3 best solutions below

1
Joseph On

If reactToChanges is just a function that sets up "listeners" for myRactive and is never called elsewhere, you can probably put the code for it in an oninit. This way, you have access to the instance.

function renderDocsSomehow() {
    let myRactive = new Ractive({
      el: '#myDiv',
      template: 'my Template',
      //magic: true,
      data:{
        doc1: docs
      },
      components: {myComponents},
      computed: {computedValues},
      oninit(){
        //here my changes appear
        onUpdatedOrInserted(change.doc);
        this.update()
      }
    });
}
0
Torf On

I found some sort of answer and thought I'd share it, even if it is not working 100% as desired.

If I return ractive from my first function It's usable in the second one:

fetchInitialDocs().then(renderDocsSomehow).then(reactToChanges).catch(console.log.bind(console));

function renderDocsSomehow() {
    let myRactive = new Ractive({
      el: '#myDiv',
      template: 'my Template',
      data:{
        doc1: docs
      },
      components: {myComponents},
      computed: {computedValues}
    });
    return myRactive;
}
function reactToChanges() {
    //here my changes appear
    onUpdatedOrInserted(change.doc);
    renderDocsSomehow().update() 
}

Sadly update()changes the whole ractive part of my page to its default state (every accordion that was folded out before is reverted and every chart.js is redrawn), which of course is not desirable in a highly dynamic application. Therefore I will nor mark it as answer by now.

0
ZenitoGR On

you can add the function in the new Ractive ({ here }) with the following syntax:

fetchInitialDocs().then(renderDocsSomehow).then(reactToChanges).catch(console.log.bind(console));

function renderDocsSomehow() {
    let myRactive = new Ractive({
      el: '#myDiv',
      template: 'my Template',
      //magic: true,
      data:{
        doc1: docs
      },
      components: {myComponents},
      computed: {computedValues},
      reactToChanges: function() {
        //here my changes appear
        onUpdatedOrInserted(change.doc);
        myRactive.update()
      });
}