mcpField
A
angular-directives

angular-directives

github.com/oguzhan18開発7176 回インストール31 週間前に更新
リポジトリ

angular-directives について

Angular 21でディレクティブを作成、保守する開発者向けの解説スキルです。ディレクティブのパターンや新しいAPI、再利用しやすく役割を絞るための指針を説明します。

主な機能

  1. 01属性型・構造型ディレクティブのパターン
  2. 02hostDirectivesによる合成
  3. 03シグナル入力とスタンドアロンディレクティブ
  4. 04TemplateRefとViewContainerRefの利用
  5. 05役割を絞った設計と明確なセレクター

活用シーン

  1. 01再利用可能な要素動作の作成
  2. 02条件付き埋め込みビューの構築
  3. 03コンポーネント上でのディレクティブ合成
  4. 04ディレクティブへのリアクティブ入力追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/oguzhan18/angular-ecosystem-skills --skill angular-directives

インストール後、Claude Code で/angular-directivesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/discussions/
_INDEX.md
references/docs/
_INDEX.md
references/issues/
_INDEX.md
references/releases/
_INDEX.md

詳細

Angular ディレクティブ

バージョン: Angular 21(2025) タグ: ディレクティブ、コンポーネント、DOM、カスタムディレクティブ

参考資料: ディレクティブガイド • 属性ディレクティブ • 構造ディレクティブ

API の変更

このセクションでは、最近のバージョン固有の API の変更について説明します。

  • NEW:ディレクティブ合成 API — hostDirectives を使ってディレクティブを合成します source

  • NEW:ディレクティブのシグナル入力 — input() を使ってリアクティブなディレクティブのプロパティを定義します

  • NEW:スタンドアロンディレクティブ — すべてのディレクティブをスタンドアロンにできます

  • NEW:制御フロー構文 — @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]' })

コメント