简体   繁体   English

如何在 Angular 模板中获取元素引用而不是组件引用

[英]How to get element reference in Angular template instead of component reference

Consider the following template:考虑以下模板:

<my-component #ref></my-component>
<my-comp-2 [maxWidth]="ref.clientWidth"></my-comp-2>

My component doesn't have a .clientWidth property on it, but the element itself that hosts my component does.我的组件没有.clientWidth属性,但托管我的组件的元素本身有。

Is there a name I could use or some other similar solution for getting a reference to the element itself in the HTML alone?是否有我可以使用的名称或其他类似的解决方案来单独获取对 HTML 中元素本身的引用? For instance, I would like to do something like this:例如,我想做这样的事情:

<my-component #ref="element"></my-component>

The problem is that there is no directive with the exportAs option named "element".问题是没有带有名为“element”的exportAs选项的指令。 Nor is there any built-in equivalent documented on the Angular site. Angular 站点上也没有记录任何内置等效项。

I am aware that I could add clientWidth as a property, and that I could get a reference to the element within <my-component> class via ElementRef<HTMLElement> and dependency injection, but I would like a solution that involves HTML alone.我知道我可以将clientWidth添加为属性,并且我可以通过ElementRef<HTMLElement>和依赖项注入获得对<my-component> class 中元素的引用,但我想要一个单独涉及 HTML 的解决方案。 Does such a solution exist?这样的解决方案存在吗?

I feel that your answer is the correct, but as curiosity , you can make a hard-work-around: create a directive like我觉得你的答案是正确的,但出于好奇,你可以努力解决:创建一个像这样的指令

@Directive({
  selector: '[element-directive]',
  exportAs: 'ngDirective',
})
export class MyDirective {
  constructor(public elementRef: ElementRef){}
}

And use并使用

<my-component element-directive #ref="ngDirective">
</my-component>
<my-comp-2 [style.max-width]="ref.elementRef.nativeElement.offsetWidth+'px'">
</my-comp-2>

The other way, as you indicate, is in constructor of my-component, inject ElementRef and make it public正如您所指出的,另一种方法是在我的组件的构造函数中,注入 ElementRef 并将其公开

constructor(public elementRef:ElementRef){}

Then, you can use然后,您可以使用

<my-comp-2 [style.max-width]="ref.elementRef.nativeElement.offsetWidth+'px'">
</my-comp-2>

Or you can create any function in my-component that return what do you want and call this function或者你可以在我的组件中创建任何 function 返回你想要什么并调用这个 function

NOTE: I use style.max-width, I don't know if your my-comp2 has an input or not注意:我使用 style.max-width,我不知道你的 my-comp2 是否有输入

The DirectiveBinder class in the Angular compiler package appears to treat any non-named template reference as a reference to the component (if it is one) or the element (if it's not). Angular 编译器 package 中的DirectiveBinder class似乎将任何未命名模板引用视为对组件(如果它是一个)或元素(如果不是)的引用。

The relevant code is here:相关代码在这里:

  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 && 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);
    }
  });

The first if branch is when no name is given (ie #ref or #ref="" ) and the else loops through any directives on the element being checked.第一个 if 分支是在没有给出名称时(即#ref#ref="" ),else 循环遍历被检查元素上的任何指令。 Above this shows that no directives is a possibility, suggesting that there isn't some place where a special built-in "element" directive is being added.上面这表明没有指令是可能的,这表明没有在某些地方添加特殊的内置“元素”指令。

Conclusion 1: If it's a component and there is no name in the template reference variable, then it will always refer to the component.结论1:如果它是一个组件并且模板引用变量中没有名称,那么它总是引用该组件。

Conclusion 2: There are no special built-in directives in every case.结论 2:在每种情况下都没有特殊的内置指令。 Exceptions may exist for some standard HTML elements (eg <input> ), but that doesn't help us here.某些标准 HTML 元素(例如<input> )可能存在例外情况,但这对我们没有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM