为自定义属性创建新的绑定上下文
Create a new binding context for a custom attribute
我想要的
<div amazingattr.bind="foo">
${$someValueFromAmazingattr}
</div>
就像这样工作:
<div repeat.for="bar of bars">
${$index}
</div>
我卡在哪里
import {customAttribute} from "aurelia-framework";
@customAttribute("amazingattr")
export class AmazingattrCustomAttribute {
bind(binding, overrideContext) {
this.binding = binding;
}
valueChanged(newValue) {
this.binding.$someValueFromAmazingattr = newValue;
}
}
虽然这有效,但 $someValueFromAmazingattr
在自定义属性的元素之外共享,所以这不起作用:
<div amazingattr.bind="foo">
Foo: ${$someValueFromAmazingattr}
</div>
<div amazingattr.bind="bar">
Bar: ${$someValueFromAmazingattr}
</div>
"Foo:" 和 "Bar:" 都显示相同的上次修改值,因此 foo
或 bar
发生变化,两者都绑定到该值。
为什么我需要这个?
我正在研究一个价值动画师,所以虽然我不能写这个(因为价值转换器不能这样工作):
${foo | animate:500 | numberFormat: "0.0"}
我可以这样写:
<template value-animator="value:foo;duration:500">
${$animatedValue | numberFormat: "0.0"}
</template>
我想我需要指示 aurelia 为自定义属性创建新的绑定上下文,但我找不到执行此操作的方法。我研究了 repeat.for
的实现,但那太复杂了,我可以弄清楚。 (不同之处还在于创建多个视图,我不需要)
经过许多小时的搜索,我发现了 aurelia 的 with
自定义元素,并对解决方案进行了某种逆向工程。
免责声明:这行得通,但我不知道这是否是正确的做法。我确实在嵌入式视图 (if.bind
) 中测试了这个解决方案,确实包含了父属性,写了父属性,一切似乎都有效,但是其他一些绑定解决方案似乎也有效。
import {
BoundViewFactory,
ViewSlot,
customAttribute,
templateController,
createOverrideContext,
inject
} from "aurelia-framework";
@customAttribute("amazingattr")
@templateController //This instructs aurelia to give us control over the template inside this element
@inject(BoundViewFactory, ViewSlot) //Get the viewFactory for the underlying view and our viewSlot
export class AmazingattrCustomAttribute {
constructor(boundViewFactory, viewSlot) {
this.boundViewFactory = boundViewFactory;
this.viewSlot = viewSlot;
}
bind(binding, overrideContext) {
const myBindingContext = {
$someValueFromAmazingattr: this.value //Initial value
};
this.overrideContext = createOverrideContext(myBindingContext, overrideContext);
//Create our view, bind it to our new binding context and add it back to the DOM by using the viewSlot.
this.view = this.boundViewFactory.create();
this.view.bind(this.overrideContext.bindingContext, overrideContext);
this.viewSlot.add(this.view);
}
unbind() {
this.view.unbind(); //Cleanup
}
valueChanged(newValue) {
//`this.overrideContext.bindingContext` is the `myBindingContext` created at bind().
this.overrideContext.bindingContext.$someValueFromAmazingattr = newValue;
}
}
我想要的
<div amazingattr.bind="foo">
${$someValueFromAmazingattr}
</div>
就像这样工作:
<div repeat.for="bar of bars">
${$index}
</div>
我卡在哪里
import {customAttribute} from "aurelia-framework";
@customAttribute("amazingattr")
export class AmazingattrCustomAttribute {
bind(binding, overrideContext) {
this.binding = binding;
}
valueChanged(newValue) {
this.binding.$someValueFromAmazingattr = newValue;
}
}
虽然这有效,但 $someValueFromAmazingattr
在自定义属性的元素之外共享,所以这不起作用:
<div amazingattr.bind="foo">
Foo: ${$someValueFromAmazingattr}
</div>
<div amazingattr.bind="bar">
Bar: ${$someValueFromAmazingattr}
</div>
"Foo:" 和 "Bar:" 都显示相同的上次修改值,因此 foo
或 bar
发生变化,两者都绑定到该值。
为什么我需要这个?
我正在研究一个价值动画师,所以虽然我不能写这个(因为价值转换器不能这样工作):
${foo | animate:500 | numberFormat: "0.0"}
我可以这样写:
<template value-animator="value:foo;duration:500">
${$animatedValue | numberFormat: "0.0"}
</template>
我想我需要指示 aurelia 为自定义属性创建新的绑定上下文,但我找不到执行此操作的方法。我研究了 repeat.for
的实现,但那太复杂了,我可以弄清楚。 (不同之处还在于创建多个视图,我不需要)
经过许多小时的搜索,我发现了 aurelia 的 with
自定义元素,并对解决方案进行了某种逆向工程。
免责声明:这行得通,但我不知道这是否是正确的做法。我确实在嵌入式视图 (if.bind
) 中测试了这个解决方案,确实包含了父属性,写了父属性,一切似乎都有效,但是其他一些绑定解决方案似乎也有效。
import {
BoundViewFactory,
ViewSlot,
customAttribute,
templateController,
createOverrideContext,
inject
} from "aurelia-framework";
@customAttribute("amazingattr")
@templateController //This instructs aurelia to give us control over the template inside this element
@inject(BoundViewFactory, ViewSlot) //Get the viewFactory for the underlying view and our viewSlot
export class AmazingattrCustomAttribute {
constructor(boundViewFactory, viewSlot) {
this.boundViewFactory = boundViewFactory;
this.viewSlot = viewSlot;
}
bind(binding, overrideContext) {
const myBindingContext = {
$someValueFromAmazingattr: this.value //Initial value
};
this.overrideContext = createOverrideContext(myBindingContext, overrideContext);
//Create our view, bind it to our new binding context and add it back to the DOM by using the viewSlot.
this.view = this.boundViewFactory.create();
this.view.bind(this.overrideContext.bindingContext, overrideContext);
this.viewSlot.add(this.view);
}
unbind() {
this.view.unbind(); //Cleanup
}
valueChanged(newValue) {
//`this.overrideContext.bindingContext` is the `myBindingContext` created at bind().
this.overrideContext.bindingContext.$someValueFromAmazingattr = newValue;
}
}