Itérateur RactiveJS avec comportement au clic
-
23-12-2019 - |
Question
J'essaie de déclencher une fonction qui fait partie de l'objet de données que je transmets à RactiveJS lors du remplissage d'un modèle.J'ai essayé quelques autres bibliothèques, mais je ne trouve pas ce que je cherche.Voici la description de ce que je fais, et j'espère que quelqu'un pourra suggérer une bibliothèque pour faire ce que j'essaie de faire.
Un service alimente mon application avec un objet JSON qui ressemble à ceci
var data = {
"users": {
"Aaron": {
"age": "31",
"level": "legit",
"talk": function(){
console.log("Howdy! I'm " + this.level);
}
},
"Pete": {
"age": "30",
"level": "godlike",
"talk": function(){
console.log("Howdy! I'm " + this.level);
}
}
}
};
Mon modèle semble être correct Comme indiqué par le Documentation
var usersTemplate = "<ul>{{#users:name}}<li><a href='#' on-click='talk'>{{name}} says:</li>{{/users}}</ul>";
Ensuite, je construis une nouvelle instance Ractive
var people = new Ractive({
el: "#userlist",
template: usersTemplate ,
data: data
});
Le problème est que cliquer sur chaque utilisateur ne fera rien car RactiveJS ne semble pas fonctionner comme ça.Il gère des événements comme ce.
people.on({
talk: function(evt){
evt.original.preventDefault();
console.log("I clicked on the template");
}
});
Ce que j'essaie de faire, c'est de déclencher le action
fonction à l’intérieur de l’objet de données que j’ai transmis sans que le contrôleur sache quel est le nom de la méthode.Le spécifier dans le modèle et dans l'objet de données devrait suffire.
Ractive donne suffisamment d'informations pour que je puisse parcourir l'objet de données, mais ce n'est pas suffisant.
people.on({
talk: function( evt ) {
evt.original.preventDefault();
var pointer = json_output;
var path = evt.keypath.split(".");
for( var i = 0; i < path.length; i++){
console.log(i);
pointer = pointer[path[i]];
}
if(pointer.hasOwnProperty("action") && typeof(pointer.action) === "function") {
pointer.action(evt);
}
}
});
RactiveJS n'est-il pas la bonne bibliothèque pour ce travail ?Merci d'avance de m'aider dans ma recherche.
La solution
tandis que Ractive ne vous permet pas d'appeler des fonctions directement, il prend en charge les arguments de l'événement, il y a donc une très belle solution de contournement pour cela:
<a on-click="call:talk">Talk</a>
var ractive = new Ractive({
el: "#userlist",
template: usersTemplate,
data: data
});
ractive.on('call', function ( event, method ) {
event.context[method]();
});
Autres conseils
Vous pouvez simplifier votre code comme ceci :
people.on({
talk: function( evt ) {
evt.original.preventDefault();
evt.context.talk(evt)
}
});
en plus, tu peux penser à plus meta
façon de faire ça :
function getProxyHandler(eventName) {
return function(event) {
event.context[eventName](event)
}
}
de cette façon, vos événements pourraient être attribués comme :
people.on({
talk:getProxyHandler('talk'),
eat: getProxyHandler('eat')
})
En utilisant des événements personnalisés, @Martin a montré que vous pouvez modifier le gestionnaire pour appliquer ou appeler une fonction dans un événement comme ceci :
people.on('call' , function(event, method) {
method.call(event.context)
})
Existe-t-il un moyen d'automatiser la création de l'objet auquel vous passez people.on()
étant donné la valeur des attributs au clic du modèle ?Ractive supprime ces attributs au clic
Sinon, quelque chose comme ça pourrait être piraté avec jQuery
var people = new Ractive({
el: "#userlist",
template: usersTemplate,
data: data,
complete: function(){
var onHandler = {}, action;
$("[on-click]", "#userlist").each(function(e){
action = $(this).attr('on-click');
onHanlder[action] = getProxyHandler(action);
});
this.on(onHandler);
}
});