如何创建自定义属性以添加if.bind

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

本文关键字:添加 if bind 自定义属性 何创建 创建      更新时间:2023-09-26

我想创建一个属性来显示或隐藏基于某些全局状态的元素。

示例:

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

该属性将有效地转换div元素:

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

状态值转换器将数组转换为布尔值。

目标是如果当前全局状态是所提供的任何状态,则显示元素,否则隐藏它

我不想要一个包含compose的自定义元素。

Aurelia备忘单有一个naive if自定义属性的例子。我在此基础上制定了一个解决方案。唯一的区别是:

  • 计算显示或隐藏的逻辑(当然)
  • 也订阅全局状态,而不是仅订阅valueChanged

代码:

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();
    }
  }
}

或者GistRun

您可以创建一个属性并将if绑定到该属性。像这样:

import {computedFrom} from 'aurelia-framework';
export class MyViewModel {
  @computedFrom('something', 'someOtherValue')
  get globalState() {
     //do all conditions you need
     if (myArray.indexOf('something') != -1 && someOtherValue) {
       return true;
     }
     return false;
  }
}

然后你只需要绑定:

<div if.bind="globalState"></div>