Как получить ссылку на элемент в шаблоне Angular вместо ссылки на компонент

#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> ), но это нам здесь не поможет.