Search code examples
javascriptractivejs

how to determine if my ractive computed value has changed


For my Layout I have a component which needs to be initialized once rendering is completed, and then again if anything in my data changes.

This would work great, but I rely on computed values for a filtered and changed output for each client and via observe the change event is fired to often. What I do:

let myRactive = new Ractive({
    el: '#clientContainer',
    template: myTemplate,
    magic: true,
    modifyArrays: true,
    data: {data}, //=> this is an awful lot of Data changing all the Time
    computed: {
        usefulData(){
           let tempdata = this.get('data');
           //=> a lot of rearranging, filtering and sorting 
           //   to adapt the data only for this specific client
           return tempdata;
        }
   onrender: function () {
        initmyLayoutComponent()
    }
    });

So I tried to get it this way

myRactive .observe( 'usefulData', function ( newValue, oldValue, keypath)
    destroymyLayoutComponent();
    initmyLayoutComponent();
});

But this fired a) every time anything in datachanges (even when it was something completely unrelated to usefulData), and b) before ractive has rendered the DOM so the component gets re-initialized to early.

Is there a way to observe only the computed value, or - which would be even better - just observe specific actions in the computed value (like I want to react to added/deleted Objects, but not to changed Values)?


Solution

  • Well what you can do, is to actually send in a clientData obj into the template instead, and then only listen to that data.

    let myRactive = new Ractive({
      el: '#clientContainer',
      template: '<div>{{clientData.name}}</div><input type="text" value="{{clientData.name}}" /><div>{{email}}</div><input type="text" value="{{email}}" /><div>Clientdata changed: {{cnt}}</div>',
      magic: true,
      modifyArrays: true,
      data: {
        name: 'hallo',
        email: 'a@a.com',
        cnt: 0
      }, //=> this is an awful lot of Data changing all the Time
      computed: {
        usefulData() {
          let tempdata = this.get('name');
          // Create your own data obj
          tempdata = {
            name: 'world'
          };
          // set it to the ractive context
          this.set('clientData', tempdata);
        }
      },
      oninit: function() {
        this.observe('clientData', function(newValue, oldValue, keypath) {
          let cnt = this.get('cnt')
          cnt += 1;
          this.set('cnt', cnt);
          console.log('listen only to the computed data');
        }, {init: false});
        this.get('usefulData');
      },
      onrender: function() {
        // do something
      },
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/0.9.0-build-123/ractive.min.js"></script>
    <div id="clientContainer"></div>