Aurelia - пользовательский элемент не наследует контекст привязки по умолчанию. Это нормально?
Каждая модель представления получает два параметра в своем bind()
метод: bindingContext
а также overrideContext
, Первый описывает текущую область, второй - внешнюю (ые) область (и): родитель, родительский родитель и т. Д. Это выглядит примерно так:
overrideContext: {
bindingContext: {...}, //current level
parentOverrideContext: {
bindingContext: {...}, //parent's binding context
parentOverrideContext: {...} //and so on
}
}
Это позволяет методам и полям доступа модели представления также из родительских областей видимости.
Если пользовательский элемент создан, он получает ожидаемый bindingContext
а также overrideContext
параметры в bind()
, Но когда он передает их своему дочернему элементу (ren), он находится не в ожидаемом формате, а:
overrideContext: {
bindingContext: {...}, //current level, this is ok
parentOverrideContext: null,
__parentOverrideContext: {...}, //this is the real
}
Обратите внимание, что оригинал parentOverrideContext
был перемещен в __parentOverrideContext
, Таким образом, шаблонизатор не сможет ничего разрешить из области видимости родителей. Давайте приведем конкретный пример:
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
}
}
Здесь я хотел бы вызвать метод, определенный для родителя родителя (MyPage
) от кнопки в самом внутреннем виде-модели (<custom-element-2>
), но из-за другого формата шаблон не может найти родителя и не может разрешить метод.
После некоторой отладки я понял, что есть флаг (instruction.inheritBindingContext
), который определяет, должен ли родитель быть включен или нет. Флаг есть 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 {}
1 ответ
Это намеренно. Это не позволяет разработчикам создавать пользовательские элементы, которые не являются переносимыми, поскольку они зависят от определенных свойств внешней области видимости.