Aurelia - 自定义元素默认不继承绑定上下文。可以吗?

Aurelia - custom element does not inherit binding context by default. Is it okay?

每个 view-model 在其 bind() 方法中获取两个参数:bindingContextoverrideContext。第一个描述当前范围,第二个描述外部范围:parent、parent 的 parent 等。这看起来像这样:

overrideContext: {
    bindingContext: {...}, //current level
    parentOverrideContext: {
        bindingContext: {...}, //parent's binding context
        parentOverrideContext: {...} //and so on
    }
}

这也允许 view-model 从 parent 的范围访问方法和字段。

如果创建自定义元素,它会在 bind() 中接收预期的 bindingContextoverrideContext 参数。但是当它将它们传递给它的 child(ren) 时,它不是预期的格式,而是:

overrideContext: {
    bindingContext: {...}, //current level, this is ok
    parentOverrideContext: null,
    __parentOverrideContext: {...}, //this is the real
}

请注意,原来的 parentOverrideContext 已移至 __parentOverrideContext。这样,模板引擎将无法解析 parent 范围内的任何内容。举个具体的例子:

page.html:

<template>
    Hello, user!
    <custom-element-1>
        <custom-element-2>
            <button click.trigger="myHandler()">Call myHandler</button>
        </custom-element-2>
    </custom-element-1>
</template>

page.js:

export class MyPage {
    myHandler() {
        //do something here
    }
}

这里我想从最里面的 view-model (<custom-element-2>), 但由于格式不同,模板无法找到 parent 并且无法解析该方法。

经过一些调试,我意识到有一个标志 (instruction.inheritBindingContext),它决定是否应该包含 parent。默认情况下,router-views 的标志是 true,但自定义元素的标志是 false。问题:我是否没有正确理解它,这是期望的行为吗?或者这是一个错误?

无论如何,如果有人感兴趣,可以轻松更改标志:

import {customElement, processContent} from 'aurelia-templating';

@processContent((compiler, resources, node, instruction) => {
    instruction.inheritBindingContext = true;
    return true/false;
})
@customElement('custom-element-1')
export class CustomElement1 {}

这是故意的。它可以防止开发人员构建不可移植的自定义元素,因为它们依赖于外部范围的特定属性。

https://www.danyow.net/aurelia-custom-element-vs-compose/