我在文档中找不到答案,所以我在这里问。什么是绑定上下文传递给自定义元素的bind
方法。它仅仅等于路由器当前活动的ViewModel 吗?至少,这是我到目前为止所发现的。
为什么它不是元素的父(在DOM方面)VM?
使用此代码
@customElement("myelem")
@inlineView("<template><content></content></template>")
export class MyElem{
bind(ctx){
console.log(ctx);
}
}
// welcome.html
<myelem>
<h3>inside myelem</h3>
<myelem>
<h4>inside inside ... </h4>
</myelem>
</myelem>
控制台中的输出只是当前视图模型(Welcome
)打印两次。
我希望第一个(外部)Welcome
为myelem
,第二个(内部)出现MyElem
......
请解释为什么我在这里错了,内部自定义元素如何知道它的实际上下文(我的意思是上面案例中的外部上下文),而不使用像创建秘密那样丑陋的黑客属性在“共享”上下文中(实际传递给它们的那个)
答案 0 :(得分:16)
就数据绑定而言,两个元素都绑定到相同的绑定上下文。考虑这个例子:
<div foo.bind="bar">
<div foo.bind="bar"></div>
</div>
您希望两个<div>
元素具有相同的绑定上下文吗?元素的foo
属性都应绑定到同一模型的bar
属性。在这种情况下也是如此:
<myelem foo.bind="bar">
<myelem foo.bind="bar"></myelem>
</myelem>
<myelem>
的两个实例都绑定到相同的绑定上下文/模型。
如果我正确理解了这个问题,你想要一个优雅的方法来为内部MyElem类实例提供对外部MyElem类实例的引用。幸运的是,您正在使用Aurelia,因此有一种非常好的方法可以做到这一点...使用inject
装饰器将其声明为依赖:
import {inject, Parent} from 'aurelia-dependency-injection';
import {customElement} from 'aurelia-framework';
@customElement("myelem")
@inject(Parent.of(MyElem))
export class MyElem {
constructor(parent) {
this.parent = parent;
}
...
}
但有一点需要注意......
Aurelia依赖注入容器的默认行为是,如果在容器中找不到实例,则创建所请求项的实例。这意味着@inject(Parent.of(MyElem))
并不是我们想要的。在没有父MyElem实例的情况下,容器将为我们创建一个而不是返回null。通常我们会使用@inject(Optional.of(MyElem))
告诉容器只有当它存在于容器中时才能为我们提供实例。我不知道将Parent.of和Optional.of结合起来的方法。我将在aurelia依赖注入存储库中创建一个问题,以便我们可以添加此功能。
与此同时,我们可以轻松创建自己的Resolver,它结合了Parent.of和Optional.of的行为:
import {resolver} from 'aurelia-dependency-injection';
@resolver()
export class OptionalParent {
constructor(key) {
this.key = key;
}
get(container) {
if (container.parent && container.parent.hasResolver(this.key, false)) {
return container.parent.get(this.key)
}
return null;
}
static of(key) {
return new OptionalParent(key);
}
}
所以我们的MyElem类的新版本看起来像这样:
import {inject} from 'aurelia-dependency-injection';
import {customElement} from 'aurelia-framework';
import {OptionalParent} from './optional-parent';
@customElement("myelem")
@inject(OptionalParent.of(MyElem))
export class MyElem {
constructor(parent) {
this.parent = parent;
}
...
}
这是一个有效的例子。检查控制台是否有显示结果的日志消息: