Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create custom attribute to add a if.bind?

I want to create an attribute to show or hide elements based on some global state.

Example:

<div state='new,unknown'>yadayadayada</div>

This attribute will then transform the div element to be effectively:

<div if.bind="['new','unknown'] | state & signal : 'state-change'">...</div>

The state value converter will convert the array to a boolean.

The goal is if the current global state is any of the provided states, then show the element else hide it.

I don't want a custom element with compose in it.

like image 715
Johan Pretorius Avatar asked Oct 21 '25 17:10

Johan Pretorius


1 Answers

Aurelia cheat sheet has an example of naive-if custom attribute. I craft a solution based on it. The only differences are:

  • The logic to calculate show or hide (of course)
  • Subscribe to the global state too, instead of only valueChanged

Code:

import {BoundViewFactory, ViewSlot, customAttribute, templateController, inject} from 'aurelia-framework';
import {BindingEngine} from 'aurelia-binding';
import {State} from './state';

@customAttribute('naive-if')
@templateController
@inject(BoundViewFactory, ViewSlot, BindingEngine, State)
export class NaiveIf {
  constructor(viewFactory, viewSlot, bindingEngine, state) {
    this.show = false;
    this.viewFactory = viewFactory;
    this.viewSlot = viewSlot;
    this.bindingEngine = bindingEngine;
    this.state = state;
  }

  bind() {
    this.updateView();
    this.subscription = this.bindingEngine.propertyObserver(this.state, 'value')
      .subscribe((newValue, oldValue) => this.updateView());
  }

  unbind() {
    if (this.subscription) this.subscription.dispose();
  }

  valueChanged(newValue) {
    this.updateView();
  }

  updateView() {
    let isShowing = this.show;
    let showStates = this.value.split(',');
    this.show = showStates.indexOf(this.state.value) != -1;

    if (this.show && !isShowing) {
      let view = this.viewFactory.create();
      this.viewSlot.add(view);
    } else if (!this.show && isShowing) {
      this.viewSlot.removeAll();
    }
  }
}

Or GistRun

like image 129
qtuan Avatar answered Oct 23 '25 05:10

qtuan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!