我有一个自定义属性来处理身份验证数据,并根据说明做一些有趣的事情。
<div auth="disabled: abc; show: xyz; highlight: 123">
这里发生了许多复杂而微妙的事情,将它与disabled.bind
等语义绑定分开是有意义的。但是,一些元素也会有应用程序逻辑级绑定。
<div auth="disabled.bind: canEdit" disabled.bind="!editing">
在封面下,我的auth属性查看登录用户,确定用户是否具有正确的权限,并根据结果采取正确的操作。
disabledChanged(value) {
const isDisabled = this.checkPermissions(value);
if (isDisabled) {
this.element.disabled = true;
}
}
此结果需要覆盖其他绑定,这些绑定可能存在也可能不存在。理想情况下,我希望寻找现有的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();
}
}
问题是这个getBindings(element)
功能是什么?如何访问元素上的任意绑定?
修改:请点击此处:https://gist.run/?id=4f2879410506c7da3b9354af3bcf2fa1
答案 0 :(得分:5)
disabled
属性只是一个元素属性,因此您只需使用内置的API即可。在这里查看一个可运行的示例:https://gist.run/?id=b7fef34ea5871dcf1a23bae4afaa9dde
使用setAttribute
和removeAttribute
(因为disabled
属性实际上没有值,它的存在会导致元素被禁用),只需要发生这一切:< / p>
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);
}
}
以下的新回应
您需要直接使用绑定引擎。可运行的要点位于:https://gist.run/?id=b7fef34ea5871dcf1a23bae4afaa9dde
基本上,您需要获取原始绑定表达式,对其进行缓存,然后使用绑定表达式auth === false
替换它(如果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);
}
}
重要的是,属性在自身之后清理,就像我在unbind
回调中一样。我会说实话,我不确定在解除绑定时对rebind
的调用是否真的是必要的,但它是完整的。