angular2 指令可以访问它所应用的组件的模板吗?
Can an angular2 directive access the template of a component it's applied to?
由于 Gunter 的回答而更新,现在我更好地理解了我的问题:
如果我正在编写自定义指令并计划将其应用于组件,那么让我的指令查询该组件模板的最佳方式是什么?
我正在编写一个属性指令,其 objective 只是更改它在其宿主中找到的第一个自定义按钮组件的样式。如果主机本身是我的自定义按钮组件,它会出于某种原因出现在我的指令的 ContentChildren 查询中。如果主机在其模板中包含我的自定义按钮组件,我的指令将找不到它。
这是我的指令:
import { Directive, AfterViewInit, AfterContentInit, ContentChildren, QueryList, ViewChild, ElementRef } from '@angular/core';
import { MyCustomButtonComponent } from './my-custom-button.component';
@Directive({
selector: '[specialButton]'
})
export class SpecialButtonDirective implements AfterViewInit, AfterContentInit {
hostElement: ElementRef;
@ViewChild(MyCustomButtonComponent) myCustomButtonViewChild;
@ContentChildren(MyCustomButtonComponent, {descendants: true}) myCustomButtonQueryList: QueryList<MyCustomButtonComponent>;
constructor(el: ElementRef) {
this.hostElement = el;
}
ngOnInit() {
//Should I query here? Via this.hostElement.nativeElement.querySelector(...) perhaps?
}
ngAfterContentInit(): void {
console.log('Value of myCustomButtonQueryList.first [' + this.myCustomButtonQueryList.first + ']');
}
ngAfterViewInit(): void {
console.log('Value of myCustomButtonViewChild [' + this.myCustomButtonViewChild + ']');
}
}
然后在我的主要组件中,它的指令中包含 MyCustomButtonComponent 和 SpecialButtonDirective:
<my-custom-button specialButton>Host is Button</my-custom-button>
<!-- Value of myCustomButtonQueryList.first [[object Object]] -->
<!-- Value of myCustomButtonViewChild [undefined] -->
<!--The dropdown toggle button is a my-custom-button in my-custom-dropdown's template -->
<my-custom-dropdown specialButton>
<ul>
<li><div>Item 1</div></li>
<li><div>Item 2</div></li>
</ul>
</my-custom-dropdown>
<!-- Value of myCustomButtonQueryList.first [undefined] -->
<!-- Value of myCustomButtonViewChild [undefined] -->
我不明白为什么第一个示例找到我的自定义按钮组件,因为我认为 ContentChildren 只在 ng-content 标签内搜索,但它正在获取主机 MyCustomButtonComponent。
而且我不明白为什么第二个示例不起作用,因为我认为 ViewChild 应该搜索 my-custom-dropdown 的模板?但是它没有在其中找到 MyCustomButtonComponent 的实例。
指令没有视图,因此 @ViewChild()
无效。 @ContentChildren()
虽然支持。
由于 Gunter 的回答而更新,现在我更好地理解了我的问题:
如果我正在编写自定义指令并计划将其应用于组件,那么让我的指令查询该组件模板的最佳方式是什么?
我正在编写一个属性指令,其 objective 只是更改它在其宿主中找到的第一个自定义按钮组件的样式。如果主机本身是我的自定义按钮组件,它会出于某种原因出现在我的指令的 ContentChildren 查询中。如果主机在其模板中包含我的自定义按钮组件,我的指令将找不到它。
这是我的指令:
import { Directive, AfterViewInit, AfterContentInit, ContentChildren, QueryList, ViewChild, ElementRef } from '@angular/core';
import { MyCustomButtonComponent } from './my-custom-button.component';
@Directive({
selector: '[specialButton]'
})
export class SpecialButtonDirective implements AfterViewInit, AfterContentInit {
hostElement: ElementRef;
@ViewChild(MyCustomButtonComponent) myCustomButtonViewChild;
@ContentChildren(MyCustomButtonComponent, {descendants: true}) myCustomButtonQueryList: QueryList<MyCustomButtonComponent>;
constructor(el: ElementRef) {
this.hostElement = el;
}
ngOnInit() {
//Should I query here? Via this.hostElement.nativeElement.querySelector(...) perhaps?
}
ngAfterContentInit(): void {
console.log('Value of myCustomButtonQueryList.first [' + this.myCustomButtonQueryList.first + ']');
}
ngAfterViewInit(): void {
console.log('Value of myCustomButtonViewChild [' + this.myCustomButtonViewChild + ']');
}
}
然后在我的主要组件中,它的指令中包含 MyCustomButtonComponent 和 SpecialButtonDirective:
<my-custom-button specialButton>Host is Button</my-custom-button>
<!-- Value of myCustomButtonQueryList.first [[object Object]] -->
<!-- Value of myCustomButtonViewChild [undefined] -->
<!--The dropdown toggle button is a my-custom-button in my-custom-dropdown's template -->
<my-custom-dropdown specialButton>
<ul>
<li><div>Item 1</div></li>
<li><div>Item 2</div></li>
</ul>
</my-custom-dropdown>
<!-- Value of myCustomButtonQueryList.first [undefined] -->
<!-- Value of myCustomButtonViewChild [undefined] -->
我不明白为什么第一个示例找到我的自定义按钮组件,因为我认为 ContentChildren 只在 ng-content 标签内搜索,但它正在获取主机 MyCustomButtonComponent。
而且我不明白为什么第二个示例不起作用,因为我认为 ViewChild 应该搜索 my-custom-dropdown 的模板?但是它没有在其中找到 MyCustomButtonComponent 的实例。
指令没有视图,因此 @ViewChild()
无效。 @ContentChildren()
虽然支持。