Computed property name for a computed Ractive object

31 views
Skip to first unread message

fayway

unread,
Feb 1, 2017, 9:57:15 AM2/1/17
to Ractive.js
Hi,

I have this special case

const root = new Ractive({
 el
: 'root',
  components
: {
 
Decorator
 
},
 
template: `
  <Decorator>
      <div>Got the value: {{source['key']}}</div>
      <div>Got the value: {{source['bob']}}</div>
    </Decorator>
  `

})


where the source array is a computed object provided by the Decorator component below. This object is not initialized in advance, I need to know what keypath ('key' or 'bob' in this example) was called and generate a new value on the fly



const Decorator = Ractive.extend({
 
template: '{{>content}}',
  computed
: {
  source
() {
   
const obj = {
       
get key() { //Just to test
         
return 'I know this key';
       
},
       
get ['expr']() { //How to know the expr ?
         
return `I don't know this key ${IsThereAWayToKnowWhatPropertyWeWereTryingToAccess}`;
       
}
     
};
     
return obj;
   
}
 
}
});


Thanks in advance

fayway

unread,
Feb 1, 2017, 10:04:41 AM2/1/17
to Ractive.js
Sorry my question was not explicit :)

Is there a way to know inside the computed function what specific keypath we were trying to access when displaying the computed object?

I hope it's clair

Chris Reeves

unread,
Feb 1, 2017, 1:35:55 PM2/1/17
to Ractive.js
I don't think there's really a way to accomplish what you're trying to do with property access. You could turn it into just a function that takes a path as a parameter, splits the path, and walks to the correct position in the object tree to return the value. I'm not entirely sure what your goal is though. There is definitely no public api to get the property access portion of a reference expression.


Thanks, Chris

--
You received this message because you are subscribed to the Google Groups "Ractive.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

fayway

unread,
Feb 1, 2017, 3:41:34 PM2/1/17
to Ractive.js
Thank you Chris for taking time to answer me.

Here is a concret use case: My decorator is for example an i18n decorator that should translate its children keys, it doesn't know in advance what keys its children will try to display but knows how translate a given key 



i18next
.init({
  lng
: 'en',
  resources
: {
    en
: {
      translation
: {
       
"key": "hello world"
     
}
   
},
    fr
: {
      translation
: {
       
"key": "salut le monde"
     
}
   
}
 
}
});


Ractive.components.I18nextDecorator = Ractive.extend({
 
template: '{{>content}}',  
  data
() {
   
return {
    language
: i18next.language,
    translate
(key) {
     
return i18next.t(key);
   
}
   
}
 
}
});

This works fine when using it this way

const root = new Ractive({
 el
: 'root',

 
template: `
    <I18nextDecorator>
      <div>Key1: {{translate('key')}}</div>
    </I18nextDecorator>
  `

})

The problem is that the translate method should behave like a computed data when this.get('language') change in the I18nextDecorator after a user action.

In this complete jsfiddle example https://jsfiddle.net/fayway/4cLfuL5a/, when I change the language after a certain timeout, I can't figure out how to re execute the {{translate('key')}}, this is why I tried in my first email to pass via a computed array that I tried to fill in the fly with the requested key and its translation

Do you think is it possible somehow?

Thanks in advance

Regards 






Thanks, Chris

To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+...@googlegroups.com.

Chris Reeves

unread,
Feb 1, 2017, 4:03:01 PM2/1/17
to Ractive.js
Well, the simplest solution would be to simply move the i18n function out of a component and into the root ractive instance. If you want to maintain a component hierarchy for this, you will need mappings between the component and root for `language`.

With edge, there is a `@shared` keypath that is global among ractive instances, which would make this much simpler, as you could have `@shared.translate()` and `@shared.language`. That makes it a bit more obvious that those are not instance specific/inherited data.

Here's the translate function moved into the root instance: https://jsfiddle.net/4cLfuL5a/3/. That works because `translate` subscribes to any keypaths that it `get`s (capture), and when `language` updates, ractive knows it needs to recompute all of the `translate()` calls.


Thanks, Chris

To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+unsubscribe@googlegroups.com.

fayway

unread,
Feb 1, 2017, 4:26:38 PM2/1/17
to Ractive.js
The reason why I didn't move the translate method to the root Ractive is that I have tons of those "root" Ractive :) 
I tired to avoid duplication by making the i18n Decorator where I tried to centralize the language observation mechanism...

I didn't know that data functions can be re executed like computed data just by putting a get in its body! good to know, thank you!

Thank you also for the edge new features preview :)

Regards

Marty Nelson

unread,
Feb 1, 2017, 6:42:32 PM2/1/17
to fayway, Ractive.js
If you add a get to language, then the translate function will be dependent upon it:

    translate(key) {
//create a dependency on language  
        this.get('language')
        return i18next.t(key);
    }

Add an listener on i18next:

    i18next.on('languageChanged', () => {
        this.set('language', i18next.language);
    });


To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+unsubscribe@googlegroups.com.

fayway

unread,
Feb 7, 2017, 2:50:18 AM2/7/17
to Ractive.js, fay...@gmail.com
Thank you Marty, that's exactly what I was looking for, how to create the dependency on a specific data from a template method was the missing piece 
Reply all
Reply to author
Forward
0 new messages