Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Computed binding doesn't work with on-click (Polymer)

<template is="dom-repeat" items="{{myItems}}">
    <div on-click="{{ComputedBindingFunction(item)}}">Foo</div>
</template>

This yields an error saying:

listener method {{ComputedBindingFunction(item)}} not defined

Shouldn't the function be executed, instead of literally trying to attach the function name with {{}}'s to on-click according to the docs?

Note that ComputedBindingFunction returns a function.

like image 310
Derek 朕會功夫 Avatar asked Jun 15 '15 23:06

Derek 朕會功夫


2 Answers

The example shown in the documentation you link to isn't for calling methods or firing events, it's for using computed bindings.

i.e.

<div>{{ComputedBindingFunction(item)}}</div>

If you're your trying to trigger an event, remove the braces:

<div on-click="ComputedBindingFunction"></div>

...

Access item from the triggered event

ComputedBindingFunction: function(event){
   _ComputedBindingFunction(event.model.item)
}
like image 115
miyamoto Avatar answered Nov 05 '22 19:11

miyamoto


Firstly, Attributes for event listeners (e.g., on-click, on-tap, etc) don't allow computed bindings as an argument, only a string.

Secondly, even if they did, which would be super cool in the future, your example still wouldn't work because you are returning a function from the computed binding and not a string.

Your computedFunction should instead be returning the name of the function you want to call which is defined using the arguments supplied when the event is fired.

Example:

html polymer event handler attribute

<div on-click="{{computeFunction(a, b}}">Button</div>

computeFunction makes a new function "add" and returns the name of this function as a string.

computeFunction: function(a, b) {
  functionName = "add";
  this[functionName] = function() {
    // Does whatever you want with arguments, a, b
    // Like maybe adding them together.
    return a + b
  }
  return functionName;
}

add: function(a, b) {
  return a + b;
}

This way the function called "add" which is called when the on-click event occurs would always be using the new variables "a" and "b" assigned to it.

Until this is available, which it might be never, You can store parameters in an attribute on the element which fires the event.

<div on-click="someFunction" someFunction="{{item}}">Button</div>
someFunction: function(e) {

  // Current target is the node that fired the event,
  // It has our stored parameter "{{item}}" as a value of "someFunction"
  var item = e.currentTarget.getAttribute('someFunction');

  // Do something with item
  console.log(item);
}

As you can see I stored the item in an attribute with the name of the function called by the on-click event.

This way it's easy to tell what arguments are going to be passed to the function just from looking at the html, and works for multiple event handlers on the same element.

 

like image 5
Ryan White Avatar answered Nov 05 '22 20:11

Ryan White