Angular - 获取指令的选择器名称
Angular - Get the selector name of the directive
我创建了一个带有多个选择器的指令,因此我可以使用不同的选择器访问同一个指令。我想要实现的是 获取在我的指令中调用指令 的选择器名称。
以下代码将更好地解释这一点:
所以这是我的多选择器指令:
import { Directive, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
const inputs = [
'someSelector.A', 'someSelector.B'
];
const selector = `
[someSelector.A], [someSelector.B]
`;
@Directive({ selector, inputs })
export class MyDirective implements OnInit {
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
ngOnInit() {
// I need to know here what is the current selector:
// Is it: "someSelector.A" or "someSelector.B"?
}
}
这就是我想在 HTML 中调用指令的方式:
<element *someSelector.A></element>
<!-- Or: -->
<element *someSelector.B></element>
好的,flex 的做法是将输入传递给装饰器,然后在指令上生成变量。如果指令未传递给 html 元素,则它在指令输入中未定义。它看起来像这样:
export interface DirectiveAB {
'someSelector.A': string;
'someSelector.B': number;
}
type Selectors = 'someSelector.A' | 'someSelector.B';
const inputs = ['someSelector.A', 'someSelector.B'];
@Directive({ selector: '[someSelector.A], [someSelector.B]', inputs })
export class DirectiveAB implements OnInit {
ngOnInit() {
console.log(this.hasSelector('someSelector.A'));
console.log(this.hasSelector('someSelector.B'));
}
hasSelector(selector: Selectors) {
return typeof this[selector] !== 'undefined'
}
}
<!-- prints true for "A"; false for "B" -->
<div someSelector.A></div>
<!-- prints false for "A"; true for "B" -->
<div someSelector.B></div>
您可以将指令分成两部分并扩展根指令。如果您想为不同的选择器提供不同的功能,这就是应该如何使用指令。
import { Directive } from '@angular/core';
@Directive({ selector: '*' })
export class DirectiveRoot implements OnInit {
ngOnInit() {
console.log(this);
if (this instanceof DirectiveA) {
console.log('Directive A!');
}
}
}
@Directive({ selector: '[someSelector.A]' })
export class DirectiveA extends DirectiveRoot {}
@Directive({ selector: '[someSelector.B]' })
export class DirectiveB extends DirectiveRoot {}
<!-- prints DirectiveA to the console -->
<div someSelector.A></div>
<!-- prints DirectiveB to the console -->
<div someSelector.B></div>
另一种选择是查看元素本身并检查属性是否存在:
@Directive({ selector: '[someSelector.A], [someSelector.B]' })
export class DirectiveAB implements OnInit {
constructor(private readonly ref: ViewContainerRef) {}
ngOnInit() {
console.log(this.ref.element.nativeElement.hasAttribute('someSelector.A'));
console.log(this.ref.element.nativeElement.hasAttribute('someSelector.B'));
}
}
<!-- prints true for "A"; false for "B" -->
<div someSelector.A></div>
<!-- prints false for "A"; true for "B" -->
<div someSelector.B></div>
不太确定您想要完成什么,但您可以通过几种不同的方式检查与选择器匹配的输入
@Directive({
selector: '[myDirective.A], [myDirective.B]',
})
export class MyDirective {
@Input('myDirective.A')
inputA;
@Input('myDirective.B')
inputB;
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
ngOnInit() {
if (this.inputA !== undefined) {
// used directive A
} else if (this.inputB !== undefined) {
// used directive B
}
}
}
或者您可以在 setter:
中查看
@Directive({
selector: '[myDirective.A], [myDirective.B]',
})
export class MyDirective {
@Input('myDirective.A')
set inputA(valueA) {
// will only run if A selector used
}
@Input('myDirective.B')
set inputB(valueB) {
// will only run if B selector used
}
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
}
在模板中:
<div *myDirective.A></div>
<div *myDirective.B></div>
https://stackblitz.com/edit/angular-92yazy?file=src%2Fapp%2Fapp.component.html
我创建了一个带有多个选择器的指令,因此我可以使用不同的选择器访问同一个指令。我想要实现的是 获取在我的指令中调用指令 的选择器名称。
以下代码将更好地解释这一点:
所以这是我的多选择器指令:
import { Directive, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
const inputs = [
'someSelector.A', 'someSelector.B'
];
const selector = `
[someSelector.A], [someSelector.B]
`;
@Directive({ selector, inputs })
export class MyDirective implements OnInit {
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
ngOnInit() {
// I need to know here what is the current selector:
// Is it: "someSelector.A" or "someSelector.B"?
}
}
这就是我想在 HTML 中调用指令的方式:
<element *someSelector.A></element>
<!-- Or: -->
<element *someSelector.B></element>
好的,flex 的做法是将输入传递给装饰器,然后在指令上生成变量。如果指令未传递给 html 元素,则它在指令输入中未定义。它看起来像这样:
export interface DirectiveAB {
'someSelector.A': string;
'someSelector.B': number;
}
type Selectors = 'someSelector.A' | 'someSelector.B';
const inputs = ['someSelector.A', 'someSelector.B'];
@Directive({ selector: '[someSelector.A], [someSelector.B]', inputs })
export class DirectiveAB implements OnInit {
ngOnInit() {
console.log(this.hasSelector('someSelector.A'));
console.log(this.hasSelector('someSelector.B'));
}
hasSelector(selector: Selectors) {
return typeof this[selector] !== 'undefined'
}
}
<!-- prints true for "A"; false for "B" -->
<div someSelector.A></div>
<!-- prints false for "A"; true for "B" -->
<div someSelector.B></div>
您可以将指令分成两部分并扩展根指令。如果您想为不同的选择器提供不同的功能,这就是应该如何使用指令。
import { Directive } from '@angular/core';
@Directive({ selector: '*' })
export class DirectiveRoot implements OnInit {
ngOnInit() {
console.log(this);
if (this instanceof DirectiveA) {
console.log('Directive A!');
}
}
}
@Directive({ selector: '[someSelector.A]' })
export class DirectiveA extends DirectiveRoot {}
@Directive({ selector: '[someSelector.B]' })
export class DirectiveB extends DirectiveRoot {}
<!-- prints DirectiveA to the console -->
<div someSelector.A></div>
<!-- prints DirectiveB to the console -->
<div someSelector.B></div>
另一种选择是查看元素本身并检查属性是否存在:
@Directive({ selector: '[someSelector.A], [someSelector.B]' })
export class DirectiveAB implements OnInit {
constructor(private readonly ref: ViewContainerRef) {}
ngOnInit() {
console.log(this.ref.element.nativeElement.hasAttribute('someSelector.A'));
console.log(this.ref.element.nativeElement.hasAttribute('someSelector.B'));
}
}
<!-- prints true for "A"; false for "B" -->
<div someSelector.A></div>
<!-- prints false for "A"; true for "B" -->
<div someSelector.B></div>
不太确定您想要完成什么,但您可以通过几种不同的方式检查与选择器匹配的输入
@Directive({
selector: '[myDirective.A], [myDirective.B]',
})
export class MyDirective {
@Input('myDirective.A')
inputA;
@Input('myDirective.B')
inputB;
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
ngOnInit() {
if (this.inputA !== undefined) {
// used directive A
} else if (this.inputB !== undefined) {
// used directive B
}
}
}
或者您可以在 setter:
中查看@Directive({
selector: '[myDirective.A], [myDirective.B]',
})
export class MyDirective {
@Input('myDirective.A')
set inputA(valueA) {
// will only run if A selector used
}
@Input('myDirective.B')
set inputB(valueB) {
// will only run if B selector used
}
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
}
在模板中:
<div *myDirective.A></div>
<div *myDirective.B></div>
https://stackblitz.com/edit/angular-92yazy?file=src%2Fapp%2Fapp.component.html