我正在尝试访问具有HTMLButtonElement
但没有获取按钮元素的组件内部的ng-content
。
TestComponent
@Component({
selector: 'app-test',
template: `<div>
<ng-content select="button"></ng-content>
</div>`
})
export class TestComponent implements AfterContentInit {
@ContentChildren(HTMLButtonElement)
buttons: QueryList<HTMLButtonElement>;
ngAfterContentInit() {
this.buttons.forEach(x => { //this.buttons.length is always 0
x.classList.add('btn-primary');
});
}
}
用法:
<app-test>
<button>Button1</button>
<button>Button2</button>
</app-multi-action-button>
答案 0 :(得分:2)
根据the docs,@ContentChildren()
搜索“指令类型或用于查询的名称” 。这意味着它仅适用于@Component
或@Directive
装饰的元素,或标有模板引用变量的元素(这些都不适用于您的情况)。
您可以做的是将div标记为容器,然后使用浏览器的本机API在其中查找按钮。
<div #container>
<ng-content select="button"></ng-content>
</div>
@ViewChild('container', {static: true}) containerDiv: ElementRef;
ngAfterContentInit() {
const buttons = this.containerDiv.nativeElement.querySelectorAll("button");
buttons.forEach(x => x.classList.add("btn-primary"));
}
出于好奇:如果没有{static: true}
参数,我们该怎么办?
浏览器API中有一个叫做MutationObserver
的东西。每当DOM的选定部分在各个方面(属性,节点,值)甚至整个文档发生更改时,您都可以注册要调用的回调。
请牢记以下步骤,我们可以在此处完成MutationObserver
的帮助(请检查其他Stackblitz demo):
export function buttonsObserverCallback(
mutationsList: MutationRecord[],
observer: any
) {
mutationsList.map(m => m.addedNodes).forEach(n => {
n.forEach(no => console.log(no))
});
// Use traditional 'for loops' for IE 11
for (let i = 0; i < mutationsList.length; i++) {
if (
mutationsList[i].type === "childList" &&
mutationsList[i].addedNodes.length
) {
mutationsList[i].addedNodes.forEach((node: Node) => {
if (node instanceof HTMLButtonElement) {
const $button = node as HTMLButtonElement;
if (!$button.classList.contains("btn-primary")) {
$button.classList.add("btn-primary");
}
}
});
}
}
}
第2步:创建一个Mutation观察器的实例,并向其注册上述回调
private _mutationObserver = new MutationObserver(buttonsObserverCallback);
第3步:获取角度分量的实例并进行注册以供观察
constructor(private el: ElementRef) {
this._mutationObserver.observe(el.nativeElement, {
childList: true,
subtree: true, // observe the descendants too
});
}
第4步:不要忘记最后释放观察者
ngOnDestroy() {
this._mutationObserver.disconnect();
}
答案 1 :(得分:1)
我不确定要查询HTMLButtonElement
,但是您可以尝试将模板引用变量分配给元素。尝试以下
parent.component.html
<app-test>
<button #button>Button1</button>
<button #button>Button2</button>
</app-test>
test.component.ts
export class TestComponent implements AfterContentInit {
@ContentChildren('button')
buttons: QueryList<any>;
ngAfterContentInit() {
this.buttons.forEach(x => {
console.log(x);
x.nativeElement.classList.add('btn-primary');
});
}
}
工作示例:Stackblitz