关于 angular-directives
面向 Angular 21 指令开发与维护的参考技能,说明指令模式、近期 API 变化,以及构建专注且可复用行为的实践。
主要功能
- 01属性与结构型指令模式
- 02使用 hostDirectives 组合指令
- 03信号输入与独立指令
- 04TemplateRef 和 ViewContainerRef 用法
- 05保持指令专注并使用清晰选择器
适用场景
- 01创建可复用的元素行为
- 02构建条件嵌入视图
- 03在组件上组合多个指令
- 04为指令添加响应式输入
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ oguzhan18/ angular-ecosystem-skills --skill angular-directives安装后在 Claude Code 中输入/angular-directives确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/discussions/_INDEX.mdreferences/docs/_INDEX.mdreferences/issues/_INDEX.mdreferences/releases/_INDEX.md详细介绍
Angular 指令
版本: Angular 21(2025) 标签: 指令、组件、DOM、自定义指令
API 变更
本节介绍近期特定版本的 API 变更。
-
新增:指令组合 API — 使用
hostDirectives组合指令 来源 -
新增:指令中的信号输入 — 使用
input()实现响应式指令属性 -
新增:独立指令 — 所有指令都可以是独立的
-
新增:控制流语法 — @if、@for、@switch 替代 *ngIf、*ngFor
最佳实践
- 创建属性指令,实现可复用的行为
import { Directive, ElementRef, Renderer2, Input } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
@Input() set appHighlight(color: string) {
this.renderer.setStyle(this.el.nativeElement, 'background-color', color || 'yellow');
}
constructor(private el: ElementRef, private renderer: Renderer2) {}
}
- 使用 @Input 和 @Output 实现指令间通信
@Directive({
selector: '[appClickTracker]'
})
export class ClickTrackerDirective {
@Input() trackName = 'default';
@Output() clicked = new EventEmitter<string>();
@HostListener('click')
onClick() {
this.clicked.emit(this.trackName);
}
}
- 使用 TemplateRef 创建结构型指令
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appUnless]'
})
export class UnlessDirective {
@Input() set appUnless(condition: boolean) {
if (!condition) {
this.vcRef.createEmbeddedView(this.templateRef);
} else {
this.vcRef.clear();
}
}
constructor(
private templateRef: TemplateRef<any>,
private vcRef: ViewContainerRef
) {}
}
- 使用 ViewContainerRef 实现复杂的结构逻辑
@Directive({ selector: '[appDynamic]' })
export class DynamicDirective {
constructor(
private vcr: ViewContainerRef,
private templateRef: TemplateRef<any>
) {
this.vcr.createEmbeddedView(this.templateRef);
}
}
- 使用 hostDirectives 实现组合
@Component({
selector: 'app-card',
standalone: true,
imports: [HighlightDirective],
hostDirectives: [
{
directive: HighlightDirective,
inputs: ['appHighlight: highlight']
}
],
template: `<ng-content></ng-content>`
})
export class CardComponent {}
- 对现代指令使用 standalone: true
@Directive({
selector: '[appStandalone]',
standalone: true
})
export class StandaloneDirective {}
- 在指令中使用信号
@Directive({
selector: '[appSignal]'
})
export class SignalDirective {
value = input<string>('');
ngOnInit() {
console.log(this.value());
}
}
- 使用 @HostBinding 进行属性绑定
@Directive({
selector: '[appDisable]'
})
export class DisableDirective {
@Input() set disabled(value: boolean) {
this.hostBinding.nativeElement.disabled = value;
}
constructor(private hostBinding: ElementRef) {}
}
- 保持指令专注 — 只承担一项职责
// ✅ Good - focused directive
@Directive({ selector: '[appTooltip]' })
// ❌ Bad - too many responsibilities
@Directive({ selector: '[appTooltip][appTooltipMaxWidth][appTooltipTheme]' })
- 使用描述性选择器
// ✅ Good
@Directive({ selector: '[appUserCard]' })
// ❌ Bad
@Directive({ selector: '[appUc]' })
评论
支持 Markdown