简体   繁体   中英

Rivets.js event handlers with custom arguments

I've just started with Rivets.js , which looks promising as simple data-binding framework.

I've arrived at the point that I don't know how to pass "custom arguments" to the rv-on-click binder, so I tried to take the idea from this: https://github.com/mikeric/rivets/pull/34

My code :

rivets.binders["on-click-args"] = {
  bind: function(el) {    
    model = this.model;
    keypath = this.keypath;

    if(model && keypath)
    {
        var args = keypath.split(' ');
        var modelFunction = args.shift();
        args.splice(0, 0, model);

        var fn = model[modelFunction];            
        if(typeof(fn) == "function")
        {
            this.callback = function(e) {
                //copy by value
                var params = args.slice();
                params.splice(0, 0, e);                
                fn.apply(model, params);
            }

            $(el).on('click', this.callback);
        }                        
    }
  },

  unbind: function(el) {
    $(el).off('click', this.callback);
  },

  routine: function(el, value) {    
  }
}

This code is working, my question is: is this the correct way?

If you want to pass a custom argument to the event handler then this code might be simpler:

rivets.configure({
    // extracted from: https://github.com/mikeric/rivets/issues/258#issuecomment-52489864
    // This configuration allows for on- handlers to receive arguments
    // so that you can onclick="steps.go" data-on-click="share"
    handler: function (target, event, binding) {
        var eventType = binding.args[0];
        var arg = target.getAttribute('data-on-' + eventType);

        if (arg) {
            this.call(binding.model, arg);
        } else {
            // that's rivets' default behavior afaik
            this.call(binding.model, event, binding);
        }
    }
});

With this configuration enabled, the first and only argument sent to the rv-on-click handler is the value specified by data-on-click .

<a rv-on-click="steps.go" data-on-click="homePage">home</a>

This is not my code (I found it here ), but it does work with Rivets 0.8.1.

There is also a way to pass the current context to the event handler . Basically, when an event fires, the first argument passed to the handler is the event itself (click, etc), and the second argument is the model context.

So lets say that you are dealing with a model object that is the product of a rv-each loop...

<div rv-each-group="menu.groups">
    <input rv-input="group.name"><button rv-on-click="vm.addItem">Add item</button>
    ___ more code here ___  
</div>

Then you can access the current "group" object in the event handler like this:

var viewModel = {
    addItem: function(ev, view) {
        var group = view.group;
    }
};

More details on this technique can he found here https://github.com/mikeric/rivets/pull/162

I hope this helps.

There is another answer here: https://github.com/mikeric/rivets/issues/682 by Namek:

You could define args formatter:

rivets.formatters.args = function(fn) {
    let args = Array.prototype.slice.call(arguments, 1)
    return () => fn.apply(null, args)
}

and then:

rv-on-click="on_click | args 1"

Please note that args is not a special id, you can define anything instead of args .

To pass multiple arguments use space: "on_click | args 1 2 3 'str'"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM