How to override click.delegate in a Custom Attribute

Hi,

I would like to develop a custom attribute, in which I want to override the original click.delegate binding by doing something before and after the original callback. Can someone help?

What I have done before to observe value binding changes in a custom attribute is this:

created(owningView) {
  this.valueBinding = owningView.bindings.find(b => b.target === this.element && b.targetProperty === 'value');
}

enabled() {
  this.valueBinding.targetObserver.subscribe(...);
}

I was wondering whether this is the path to investigate or if there is another way to achieve what I need.

EDIT: I only need this for HtmlButton, if this would make things considerably easier. An alternative solution would be to use the custom attribute to bind the click handler instead of the typical click.delegate, so instead of <button click.delegate="doSomething()" my-custom-attribute> I would do <button my-custom-attribute="doSomething()">, but somehow the original approach looks nicer to me.

Thanks a lot!
David

1 Like

We can
(1) Find the binding that is a click listener, with delegate strategy:

import { Listener, delegationStrategy } from 'aurelia-framework';

created(owningView) {
  this.valueBinding = owningView.bindings.find(b =>
    b instanceof Listener
    && b.target === this.element
    && b.delegationStrategy === delegationStrategy.bubling
  );
}

(2) Patch the callSource method of that binding, with your custom code:

// keep a reference to the original
const originalCallSource = valueBinding.callSource;
valueBinding.callSource = function(event) {
  // before handling click event code
  console.log('before calling view model click handler');
  const result = originalCallSource.call(valueBinding);
  console.log('after calling view model click handler');
  return result;
}

In (1), the reason we check with 3 conditions is because some one can have this on an element:

<div
  click.trigger="callTrigger($event)"
  click.delegate="callDelegate($event)">
1 Like

Thanks a lot, this is exactly what I was looking for!

1 Like