2

I am attempting to fire a function that is part of the data object I'm passing to RactiveJS when populating a template. I've tried a few other libraries, but I can't find what I'm looking for. Here is the description of what I'm doing, and I'm hopeful that someone can suggest a library for doing what I'm trying to do.

A service is feeding my application a JSON Object that looks something like this

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);
            }
        }
    }
};

My template appears to be correct As instructed by the Documentation

var usersTemplate = "<ul>{{#users:name}}<li><a href='#' on-click='talk'>{{name}} says:</li>{{/users}}</ul>";

Then I build a new Ractive instance

var people = new Ractive({
    el: "#userlist",
    template: usersTemplate ,
    data: data
});

Trouble is, clicking on each user won't actually do anything because RactiveJS doesn't seem to work like that. It handles events like this.

people.on({
    talk: function(evt){
        evt.original.preventDefault();
        console.log("I clicked on the template");
    }
});

What I'm trying to do is trigger the action function inside of the data object that I passed in without the controller knowing what the name of the method is. Specifying it in the template, and in the data object should be enough.

Ractive gives enough information that I can traverse the data object, but this isn't good enough.

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);
        }
    }
});

JSBin Example

Is RactiveJS not the right library for the job? Thank you ahead of time for helping me in my search.

4

3 回答 3

4

虽然 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]();
});
于 2014-07-31T21:16:50.047 回答
1

您可以像这样简化代码:

 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)
 })  
于 2014-07-31T19:16:20.297 回答
0

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);
  }
});
于 2014-07-31T20:06:47.423 回答