【问题标题】:Access template variables through directive in angular通过角度指令访问模板变量
【发布时间】:2018-08-22 11:25:13
【问题描述】:

我目前正在研究一个简单地操纵 dom 元素的指令。

我想访问作为指令宿主的元素的模板变量,但我不能这样做,因为结果总是未定义。

指令:

@Directive({
    selector: '[sample-directive]'
})
export class SampleDirective implements AfterViewInit {
    @ViewChild('queryMe') queryMe: ElementRef;

    ngAfterViewInit(): void {
        console.log(this.queryMe);    
    }
}

sampleComponent.template.html:

<div #queryMe></div>

用法:

<sample-component [sample-directive]></sample-component>

可以这样使用模板变量吗?

【问题讨论】:

    标签: angular angular-directive


    【解决方案1】:

    将模板变量发送到您的指令:stackblitz

    @Input('appQuery') appQuery: HTMLElement;
    
    <div [appQuery]="queryMe">
      <div #queryMe></div>
    </div>
    

    编辑

    第二种解决方案:为您的可查询元素提供自定义属性。由于模板变量只是对 HTML 元素的引用,因此您将得到几乎相同的结果(标签中多了一个属性除外)。

    Stackblitz

    get element() { return this.el.nativeElement; }
    ngAfterViewInit() {
      console.log(this.element.querySelector('[queryMe]'));
    }
    
    <div appQuery>
      <div queryMe></div>
    </div>
    

    【讨论】:

    • 谢谢,但我对模板变量的行为很好奇,我不想用我想要使用的所有元素(5 或 6)污染我的指令输入。
    • @BalázsTakács 我对我的答案进行了编辑,以防你想看到它
    【解决方案2】:

    Angular 指令没有模板。这就是它们与具有模板的 Angular 组件的不同之处。

    由于指令没有模板,您无法在它们上获取 ViewChild 或 ContentChild 之类的内容。同样出于同样的原因,您将无法实现 AfterContentInitAfterContentCheckedAfterViewInitAfterViewChecked 接口。

    因此,如果您只想要主机模板中的 HTMLElement,请给 div 一个类并使用以下指令从指令中访问它:

    import { ElementRef, Directive } from '@angular/core'
    
    @Directive({
        selector: '[sample-directive]'
    })
    export class SampleDirective {
    
        constructor(private el: ElementRef) {}
    
        ngOnInit() {
          let elYoureLookingFor = this.el.nativeElement.querySelector('.class-on-div');
        }
    
    }
    

    然后,在您的 sampleComponent.template.html 中:

    &lt;div class="class-on-div"&gt;&lt;/div&gt;

    【讨论】:

    • 我现在正在做。但我想尝试使用模板变量。事实证明,我不知道这些是如何工作的,所以我有增长知识的空间。
    • @BalázsTakács 您不能在指令类SampleDirective 中使用@ViewChild('queryMe') queryMe: ElementRef;,因为它不是您的指令SampleDirective 的子元素
    • 还有一个问题。如果指令没有这个生命周期钩子,为什么它可以与 ngAfterViewInit 函数一起使用?
    • @Amit Chigadani 这里子元素的边界是什么?因为我可以通过 viewChild 访问 SampleComponent。
    猜你喜欢
    • 2016-06-27
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2013-11-25
    • 1970-01-01
    相关资源
    最近更新 更多