#angular
#angular
Вопрос:
Рассмотрим следующий шаблон:
<my-component #ref></my-component>
<my-comp-2 [maxWidth]="ref.clientWidth"></my-comp-2>
У моего компонента нет .clientWidth
свойства, но у самого элемента, в котором размещен мой компонент, есть.
Есть ли имя, которое я мог бы использовать, или какое-либо другое подобное решение для получения ссылки на сам элемент только в HTML? Например, я хотел бы сделать что-то вроде этого:
<my-component #ref="element"></my-component>
Проблема в том, что нет директивы с exportAs
параметром с именем «элемент». На сайте Angular также нет встроенного эквивалента.
Я знаю, что я мог бы добавить clientWidth
в качестве свойства, и что я мог бы получить ссылку на элемент внутри <my-component>
класса с помощью ElementRef<HTMLElement>
и внедрения зависимостей, но я хотел бы решение, которое включает только HTML. Существует ли такое решение?
Ответ №1:
Я чувствую, что ваш ответ правильный, но, как любопытство, вы можете сделать сложную работу: создайте директиву, например
@Directive({
selector: '[element-directive]',
exportAs: 'ngDirective',
})
export class MyDirective {
constructor(public elementRef: ElementRef){}
}
И использовать
<my-component element-directive #ref="ngDirective">
</my-component>
<my-comp-2 [style.max-width]="ref.elementRef.nativeElement.offsetWidth 'px'">
</my-comp-2>
Другой способ, как вы указываете, заключается в том, чтобы в конструкторе my-component ввести ElementRef и сделать его общедоступным
constructor(public elementRef:ElementRef){}
Затем вы можете использовать
<my-comp-2 [style.max-width]="ref.elementRef.nativeElement.offsetWidth 'px'">
</my-comp-2>
Или вы можете создать любую функцию в my-component, которая возвращает то, что вы хотите, и вызвать эту
функцию
ПРИМЕЧАНИЕ: я использую style.max-width, я не знаю, есть ли у вашего my-comp2 входные данные или нет
Ответ №2:
DirectiveBinder
Класс в пакете компилятора Angular, по-видимому, обрабатывает любую ссылку на шаблон без имени как ссылку на компонент (если он один) или элемент (если это не так).).
Соответствующий код находится здесь:
node.references.forEach(ref => {
let dirTarget: DirectiveT|null = null;
// If the reference expression is empty, then it matches the "primary" directive on the node
// (if there is one). Otherwise it matches the host node itself (either an element or
// <ng-template> node).
if (ref.value.trim() === '') {
// This could be a reference to a component if there is one.
dirTarget = directives.find(dir => dir.isComponent) || null;
} else {
// This should be a reference to a directive exported via exportAs.
dirTarget =
directives.find(
dir => dir.exportAs !== null amp;amp; dir.exportAs.some(value => value === ref.value)) ||
null;
// Check if a matching directive was found.
if (dirTarget === null) {
// No matching directive was found - this reference points to an unknown target. Leave it
// unmapped.
return;
}
}
if (dirTarget !== null) {
// This reference points to a directive.
this.references.set(ref, {directive: dirTarget, node});
} else {
// This reference points to the node itself.
this.references.set(ref, node);
}
});
Первая ветвь if — это когда имя не задано (т.Е. #ref
or #ref=""
), а else перебирает любые директивы для проверяемого элемента. Выше показано, что директивы невозможны, предполагая, что нет места, где добавляется специальная встроенная директива «element».
Вывод 1: если это компонент, а в переменной ссылки шаблона нет имени, то он всегда будет ссылаться на компонент.
Вывод 2: в каждом случае нет специальных встроенных директив. Исключения могут существовать для некоторых стандартных элементов HTML (например <input>
), но это нам здесь не поможет.