Determine an Attribute's Binding Mode Within a Custom Element

I want to determine if a custom element’s bindable attribute’s binding mode is “two-way.” The only way I’ve found to do this is to get the element value within the custom element using @inject(Element), and then executing let found = element.attributes["name.two-way"]; in the custom element’s constructor.

custom-element.js

import {bindable} from 'aurelia-framework';

@inject(Element)
export class MyElement {
    @bindable() name;

    constructor (element) {
                let found = element.attributes["name.two-way"];
    }
}

consumer.html

<my-element name.bind="myName"></my-element> // found is false
<my-element name.two-way="yourName"></my-element> // found is true

Is there a better way?

1 Like

Why would you want to do this? Can you explain your use case a bit?

1 Like

Sure. My custom element will be mostly display only. However, some use cases involve allowing the user to edit one of its values. I was hoping to simply detect whether the value in question is bound two-way to determine if it can be edited by the user.

It’s sort of like putting a contenteditable attribute on a paragraph. Paragraphs are usually display only except when that attribute appears in its tag. The simplest way to allow the consuming HTML to specify it is enterable is to make the binding two-way.

I realize I could create a “sister” custom element that allows editing, but I was trying to avoid that.

1 Like

Ah ok, so it depends how the consumer wants to bind to the property. You could try to get access to the au property of the elements and look for the TargetInstructions expressions. In your case there should only be one with a single attribute. In there check for the mode.
E.g something along these lines:

import { bindable, inject, bindingMode } from "aurelia-framework";

@inject(Element)
export class MyElement {
  @bindable() name: string;

  constructor(element) {
    this.element = element;
    let found = element.au;
  }


  attached() {
    if (this.element
      .au["my-element"]
      .container
      .instruction
      .expressions[0].mode === bindingMode.twoWay) {
        console.log("This is a two way binding")
      }
  }
}

make sure to do it in the attached phase though as the constructor is too early for the au prop to be attached.

1 Like

Thank you very much!

1 Like