Итератор RactiveJS с поведением по щелчку мыши
-
23-12-2019 - |
Вопрос
Я пытаюсь запустить функцию, которая является частью объекта данных, который я передаю в RactiveJS при заполнении шаблона.Я перепробовал несколько других библиотек, но не могу найти то, что ищу.Вот описание того, что я делаю, и я надеюсь, что кто-нибудь сможет предложить библиотеку для выполнения того, что я пытаюсь сделать.
Служба передает моему приложению объект JSON, который выглядит примерно так
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);
}
}
}
};
Мой шаблон, по-видимому, верен в соответствии с инструкциями Документация
var usersTemplate = "<ul>{{#users:name}}<li><a href='#' on-click='talk'>{{name}} says:</li>{{/users}}</ul>";
Затем я создаю новый экземпляр Ractive
var people = new Ractive({
el: "#userlist",
template: usersTemplate ,
data: data
});
Проблема в том, что нажатие на каждого пользователя на самом деле ничего не даст, потому что RactiveJS, похоже, так не работает.Он обрабатывает такие события, как этот.
people.on({
talk: function(evt){
evt.original.preventDefault();
console.log("I clicked on the template");
}
});
То, что я пытаюсь сделать, это вызвать action
функция внутри объекта данных, который я передал, без того, чтобы контроллер знал, как называется метод.Указания этого в шаблоне и в объекте данных должно быть достаточно.
Ractive предоставляет достаточно информации, чтобы я мог перемещаться по объекту данных, но этого недостаточно.
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 неподходящей библиотекой для этой работы?Заранее благодарю вас за помощь в моих поисках.
Решение
Хотя Ractive не позволяет вам вызывать функции напрямую, он поддерживает аргументы событий, так что для этого есть очень хороший обходной путь:
<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]();
});
Другие советы
Вы можете упростить свой код следующим образом:
people.on({
talk: function( evt ) {
evt.original.preventDefault();
evt.context.talk(evt)
}
});
более того, вы можете подумать о большем meta
способ сделать это:
function getProxyHandler(eventName) {
return function(event) {
event.context[eventName](event)
}
}
таким образом, ваши события могут быть назначены следующим образом:
people.on({
talk:getProxyHandler('talk'),
eat: getProxyHandler('eat')
})
Используя пользовательские события, показанные @Martin, вы можете изменить обработчик для применения или вызова функции внутри события следующим образом:
people.on('call' , function(event, method) {
method.call(event.context)
})
Есть ли способ автоматизировать создание объекта, которому вы передаете people.on()
учитывая значение атрибутов шаблона при нажатии?Ractive удаляет эти атрибуты при нажатии кнопки
С другой стороны, что-то подобное можно было бы взломать вместе с 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);
}
});