Aurelia 更改元素内部的自定义属性 HTML
Aurelia Custom attribute which changes the elements inner HTML
用例
我有一个自定义属性,它可以更改附加元素的内容,例如从非粗体到粗体。
问题
使用正常绑定,内部 HTML 不会改变。我认为,一旦 HTML 更新为 "plain" Javascript.
,Aurelia 就会失去绑定
您可以在这个 GistRun 中看到它:https://gist.run/?id=6f16ac1c8affb0277d7ad5c53d433482
更改区域中的文本。有五种情况:
- 情况一:无属性。文本已更新。这很好。
- 情况2:文本没有更新。预期:更新文本,但不应该是粗体(缺失值更改调用)。
- 情况 3:文本已更新但未加粗(缺失值更改调用)。这很好。
- 情况4:文本未更新。预期:更新文本并使其变为粗体
- 案例 5:文本已更新并加粗。这很好。
问题
谁能给我解释一下,案例 2 和案例 4 内部发生了什么?
代码:
app.html
<template>
<require from="./bold-custom-attribute"></require>
<textarea value.bind="content"></textarea>
<pre>${content}</pre>
<pre bold>${content}</pre>
<pre bold textcontent.bind="content"></pre>
<pre bold.bind="content">${content}</pre>
<pre bold.bind="content" textcontent.bind="content"></pre>
</template>
大胆定制-attribute.js
export class BoldCustomAttribute {
static inject = [Element];
constructor(element) {
this.element = element;
}
bind() {
//this.bolden(this.element);
}
attached() {
this.bolden(this.element);
}
valueChanged(newValue, oldValue){
this.bolden(this.element);
}
bolden(anElement) {
anElement.innerHTML = '<b>' + anElement.innerText + '</b>';
}
}
按照您现在的方式修改 HTML,会导致创建新的 DOM 元素,因此 Aurelia 不再引用它需要的 DOM 元素更新绑定值。
通过结合 Ashley、Fabio 的 post 和正确的调试位置,我能够准确地找出发生了什么。
${content}
字符串插值都得到一个 ChildInterpolationBinding
绑定到它们形成的文本节点(在 <pre>
中,尽管在 Chrome 中不直接可见调试器),或更准确地说 textContent
属性。
这意味着,一旦 <pre>
的内部 HTML 被 bolden()
替换,文本节点就会从 DOM 中消失(但是,绑定仍然存在并且正在更新文本节点 textContent
)。新节点当然没有绑定(解释为什么案例 4 不工作)。
现在,情况 5 (textcontent.bind
) 的区别在于 Binding
直接附加到指定的 <pre>
,或更准确地说是 [=21] =] 属性。如果 <pre>
中的内容发生变化(例如通过 textContent
或 innerHTML
),绑定仍在正确的节点上 (<pre>
)。
编辑
Ashley 在这里提到的一个重点是 textcontent
绑定在 valueChanged()
之前调用。这使得案例 5 完全可行。首先,更新 textcontent
(使用不会丢失的绑定),然后触发读取刚刚更新的文本内容并应用新的 HTML 标签的值更改。
由于这一点,案例 4 适用于一个输入更改。 VM构建完成后,绑定正确,更改值工作。插值绑定正在更新文本节点,然后调用 valueChanged()
并且带有绑定的文本节点从 DOM.
中消失
我玩了一会儿,设法改变了绑定。 当然,这不应该用于生产。 添加 created()
时,一切正常 "fine"。
export class BoldCustomAttribute {
static inject = [Element];
constructor(element) {
this.element = element;
}
created(owningView, myView) {
if (this.element.hasChildNodes() && this.element.firstChild.auInterpolationTarget === true) {
owningView.bindings.forEach(binding => {
if (binding.target === this.element.firstChild) {;
binding.target = this.element;
binding.targetProperty = 'innerHTML';
}
});
}
}
bind() {
this.bolden(this.element);
}
valueChanged(newValue, oldValue){
this.bolden(this.element);
}
bolden(anElement) {
anElement.innerHTML = '<b>' + anElement.innerText + '</b>';
}
}
用例
我有一个自定义属性,它可以更改附加元素的内容,例如从非粗体到粗体。
问题
使用正常绑定,内部 HTML 不会改变。我认为,一旦 HTML 更新为 "plain" Javascript.
,Aurelia 就会失去绑定您可以在这个 GistRun 中看到它:https://gist.run/?id=6f16ac1c8affb0277d7ad5c53d433482
更改区域中的文本。有五种情况:
- 情况一:无属性。文本已更新。这很好。
- 情况2:文本没有更新。预期:更新文本,但不应该是粗体(缺失值更改调用)。
- 情况 3:文本已更新但未加粗(缺失值更改调用)。这很好。
- 情况4:文本未更新。预期:更新文本并使其变为粗体
- 案例 5:文本已更新并加粗。这很好。
问题
谁能给我解释一下,案例 2 和案例 4 内部发生了什么?
代码:
app.html
<template>
<require from="./bold-custom-attribute"></require>
<textarea value.bind="content"></textarea>
<pre>${content}</pre>
<pre bold>${content}</pre>
<pre bold textcontent.bind="content"></pre>
<pre bold.bind="content">${content}</pre>
<pre bold.bind="content" textcontent.bind="content"></pre>
</template>
大胆定制-attribute.js
export class BoldCustomAttribute {
static inject = [Element];
constructor(element) {
this.element = element;
}
bind() {
//this.bolden(this.element);
}
attached() {
this.bolden(this.element);
}
valueChanged(newValue, oldValue){
this.bolden(this.element);
}
bolden(anElement) {
anElement.innerHTML = '<b>' + anElement.innerText + '</b>';
}
}
按照您现在的方式修改 HTML,会导致创建新的 DOM 元素,因此 Aurelia 不再引用它需要的 DOM 元素更新绑定值。
通过结合 Ashley、Fabio 的 post 和正确的调试位置,我能够准确地找出发生了什么。
${content}
字符串插值都得到一个 ChildInterpolationBinding
绑定到它们形成的文本节点(在 <pre>
中,尽管在 Chrome 中不直接可见调试器),或更准确地说 textContent
属性。
这意味着,一旦 <pre>
的内部 HTML 被 bolden()
替换,文本节点就会从 DOM 中消失(但是,绑定仍然存在并且正在更新文本节点 textContent
)。新节点当然没有绑定(解释为什么案例 4 不工作)。
现在,情况 5 (textcontent.bind
) 的区别在于 Binding
直接附加到指定的 <pre>
,或更准确地说是 [=21] =] 属性。如果 <pre>
中的内容发生变化(例如通过 textContent
或 innerHTML
),绑定仍在正确的节点上 (<pre>
)。
编辑
Ashley 在这里提到的一个重点是 textcontent
绑定在 valueChanged()
之前调用。这使得案例 5 完全可行。首先,更新 textcontent
(使用不会丢失的绑定),然后触发读取刚刚更新的文本内容并应用新的 HTML 标签的值更改。
由于这一点,案例 4 适用于一个输入更改。 VM构建完成后,绑定正确,更改值工作。插值绑定正在更新文本节点,然后调用 valueChanged()
并且带有绑定的文本节点从 DOM.
我玩了一会儿,设法改变了绑定。 当然,这不应该用于生产。 添加 created()
时,一切正常 "fine"。
export class BoldCustomAttribute {
static inject = [Element];
constructor(element) {
this.element = element;
}
created(owningView, myView) {
if (this.element.hasChildNodes() && this.element.firstChild.auInterpolationTarget === true) {
owningView.bindings.forEach(binding => {
if (binding.target === this.element.firstChild) {;
binding.target = this.element;
binding.targetProperty = 'innerHTML';
}
});
}
}
bind() {
this.bolden(this.element);
}
valueChanged(newValue, oldValue){
this.bolden(this.element);
}
bolden(anElement) {
anElement.innerHTML = '<b>' + anElement.innerText + '</b>';
}
}