访问元素的绑定 [英] Access an element's Binding
问题描述
我有一个自定义属性,用于处理身份验证数据,并根据说明进行一些有趣的操作.
I have a custom attribute that processes authentication data and does some fun stuff based on the instructions.
<div auth="disabled: abc; show: xyz; highlight: 123">
这里发生了很多复杂,微妙的事情,将其与语义绑定(如disabled.bind
)分开是有意义的.但是,某些元素也将具有应用程序逻辑级别的绑定.
There's a lot of complicated, delicate stuff happening in here and it makes sense to keep it separate from semantic bindings like disabled.bind
. However, some elements will have application-logic level bindings as well.
<div auth="disabled.bind: canEdit" disabled.bind="!editing">
在幕后,我的auth属性查看登录的用户,确定该用户是否具有正确的权限,并根据结果采取正确的操作.
Under the covers, my auth attribute looks at the logged in user, determines if the user has the correct permissions, and takes the correct action based on the result.
disabledChanged(value) {
const isDisabled = this.checkPermissions(value);
if (isDisabled) {
this.element.disabled = true;
}
}
此结果需要覆盖可能存在或不存在的其他绑定.理想情况下,我想查找现有的Binding并覆盖它的ala绑定行为.
This result needs to override other bindings, which may or may not exist. Ideally, I'd like to look for an existing Binding and override it ala binding behaviors.
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)
函数是什么?如何访问元素上的任意绑定?
The question is what is this getBindings(element)
function? How can I access arbitrary bindings on an element?
编辑:要点在这里: https://gist.run/?id = 4f2879410506c7da3b9354af3bcf2fa1
推荐答案
disabled
属性只是一个元素属性,因此您可以简单地使用内置的API来执行此操作.在此处查看可运行的示例: https://gist.run/?id=b7fef34ea5871dcf1a23bae4afaa9dde
The disabled
attribute is just an element attribute, so you can simply use the built in APIs to do this. Check out a runnable example here: https://gist.run/?id=b7fef34ea5871dcf1a23bae4afaa9dde
使用setAttribute
和removeAttribute
(由于disabled
属性实际上没有值,因此,仅它的存在会导致元素被禁用),这就是需要做的所有事情:
Using setAttribute
and removeAttribute
(since the disabled
attribute does not really have a value, its mere existence causes the element to be disabled), is all that needs to happen:
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
You need to work directly with the binding engine. A runnable gist is located here: https://gist.run/?id=b7fef34ea5871dcf1a23bae4afaa9dde
基本上,您需要获取原始绑定表达式,将其缓存,然后将其(如果是auth === false
)替换为true
绑定表达式.然后,您需要取消绑定并重新绑定绑定表达式:
Basically, you need to get the original binding expression, cache it, and then replace it (if auth === false
) with a binding expression of true
. Then you need to unbind and rebind the binding expression:
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
,但这是为了完整性.
It is important that the attribute clean up after itself, as I do in the unbind
callback. I'll be honest that I'm not sure that the call to rebind
is actually necessary in the unbind, but it's there for completeness.
这篇关于访问元素的绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!