Aurelia, how to make optional binding

2019-07-14 04:21发布

问题:

Does Aurelia support optional binding? I can't find this information anywhere. The issue that I'm having is that I have a title attribute that might or might not be populated in an array of objects. I use a repeat.for and title.bind but I don't want the attribute to exist at all if this property is not part of the array of objects. Is that possible in Aurelia?

When using Bootstrap-Select with an empty title it throws an error. Having Aurelia to create attribute on the fly would resolve my issue.

The code that I have so far, looks like this

<select class="selectpicker" value.bind="value" options.bind="options" disabled.bind="disabled">
<option repeat.for="option of options" model.bind="option"
        data-subtext.bind="option.subtext"
        title.bind="option.title">
        ${option.name}
</option>

In this example, I would like to make data-subtext and title as optional attributes. Is that doable?

Since this is a Custom Element, I tried deleting the title property of my object delete this.element.title but that doesn't seem to work. I also tried with jquery but again no luck.

回答1:

I did not test this in many cases, but I think you could also create a custom binding behavior, like this:

export class OptionalBindingBehavior {  
  bind(binding, scope, interceptor) {

    binding.originalupdateTarget = binding.updateTarget;
    binding.originalTargetProperty = binding.targetProperty;
    binding.updateTarget = val => { 
      if (val === undefined || val === null || val === '') {
        binding.targetProperty = null;
      } else {
        binding.targetProperty = binding.originalTargetProperty;
      }
      binding.originalupdateTarget(val);   
    }
  }

  unbind(binding, scope) {
    binding.updateTarget = binding.originalupdateTarget;
    binding.originalupdateTarget = null;    
    binding.targetProperty = binding.originalTargetProperty;
    binding.originalTargetProperty = null;
  }
}

And then use it like:

<a href.bind="message & optional">${message}</a>


回答2:

You could use a custom-attribute that generates a title attribute only if the property exists. For example:

export class OptionalTitleCustomAttribute {

  static inject = [Element];

  constructor(element) {
    this.element = element;
  }

  valueChanged(newValue) {
    if (newValue) {
      this.element.setAttribute('title', newValue);
    } else {
      this.element.removeAttribute('title');
    }
  }

}

Running example: https://gist.run/?id=f7f89f35b62acb5b4f05ffe59be1880e