访问元素的绑定

Mat*_*vis 1 aurelia aurelia-binding

我有一个自定义属性来处理身份验证数据,并根据说明做一些有趣的事情.

<div auth="disabled: abc; show: xyz; highlight: 123">
Run Code Online (Sandbox Code Playgroud)

这里发生了许多复杂,微妙的事情,将它与语义绑定分开是有意义的disabled.bind.但是,一些元素也将具有应用程序逻辑级绑定.

<div auth="disabled.bind: canEdit" disabled.bind="!editing">
Run Code Online (Sandbox Code Playgroud)

在封面下,我的auth属性查看登录用户,确定用户是否具有正确的权限,并根据结果采取正确的操作.

disabledChanged(value) {
    const isDisabled = this.checkPermissions(value);
    if (isDisabled) {
        this.element.disabled = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

此结果需要覆盖其他绑定,这些绑定可能存在也可能不存在.理想情况下,我想查找现有的Binding并覆盖它的ala绑定行为.

constructor(element) {
    const bindings = this.getBindings(element); // What is the getBindings() function?
    const method = bindings['disabled']
    if (method) {
        bindings['disabled'] = () => this.checkPermission(this.value) && method();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是这个getBindings(element)功能是什么?如何访问元素上的任意绑定?

编辑:请点击这里:https://gist.run/ id = 4f2879410506c7da3b9354af3bcf2fa1

Ash*_*ant 5

disabled属性只是一个元素属性,因此您只需使用内置的API即可.在这里查看一个可运行的示例:https://gist.run/? id = b7fef34ea5871dcf1a23bae4afaa9dde

使用setAttributeremoveAttribute(因为disabled属性实际上没有值,它的存在会导致元素被禁用),所有这一切都需要发生:

import {inject} from 'aurelia-framework';


@inject(Element)
export class AuthCustomAttribute {
  constructor(element) {
    this.el = element;
  }

  attached() {
    let val = false;
    setInterval(() => {
      if(this.val) {
        this.el.setAttribute('disabled', 'disabled');
      } else {
        this.el.removeAttribute('disabled');
      }
      this.val = !this.val;
    }, 1000);
  }
}
Run Code Online (Sandbox Code Playgroud)

以下新回应

您需要直接使用绑定引擎.一个可运行的要点位于:https://gist.run/?id = b7fef34ea5871dcf1a23bae4afaa9dde

基本上,您需要获取原始绑定表达式,缓存它,然后用auth === false绑定表达式替换它(if )true.然后你需要取消绑定并重新绑定绑定表达式:

import {inject} from 'aurelia-framework';
import {Parser} from 'aurelia-binding';


@inject(Element, Parser)
export class AuthCustomAttribute {
  constructor(element, parser) {
    this.el = element;
    this.parser = parser;
  }

  created(owningView) {
    this.disabledBinding = owningView.bindings.find( b => b.target === this.el && b.targetProperty === 'disabled');

    if( this.disabledBinding ) {
      this.disabledBinding.originalSourceExpression =  this.disabledBinding.sourceExpression;

      // this expression will always evaluate to true
      this.expression = this.parser.parse('true');
    }
  }

  bind() {
    // for some reason if I don't do this, then valueChanged is getting called before created
    this.valueChanged();
  }

  unbind() {
    if(this.disabledBinding) {
      this.disabledBinding.sourceExpression =  this.disabledBinding.originalSourceExpression;
      this.disabledBinding.originalSourceExpression = null;

      this.rebind();

      this.disabledBinding = null;
    }
  }

  valueChanged() {
    if(this.disabledBinding ) {
      if( this.value === true ) {
        this.disabledBinding.sourceExpression =  this.disabledBinding.originalSourceExpression;
      } else {
        this.disabledBinding.sourceExpression = this.expression;
      }

      this.rebind();

    } else {
      if( this.value === true ) {
        this.el.removeAttribute('disabled');
      } else {
        this.el.setAttribute('disabled', 'disabled');
      } 
    }
  }

  rebind() {
    const source = this.disabledBinding.source;
    this.disabledBinding.unbind();
    this.disabledBinding.bind(source);
  }
}
Run Code Online (Sandbox Code Playgroud)

重要的是,属性在自身之后清理,就像我在unbind回调中那样.我会说实话,我不确定这个呼叫rebind在解除绑定中是否真的有必要,但它是完整的.

  • 我已经更新了答案和要点.它做你想要的.下次你在城里的时候,我欠你的午餐:-) (5认同)