1

入力として言語 (または言語のセット) を受け取り、ディレクティブが追加された DOM 要素にクラスを追加するディレクティブを実装しています。

@Directive({
  selector: '[appRtlView]'
})
export class RTLViewDirective implements OnInit, OnChanges {
  @Input('appRtlView') inputLanguage: string | string[];

  constructor(private el: ElementRef) {}

  ngOnInit() {
    this.handleRtl();
  }

  private handleRtl() {
    if (this.inputLanguage) {
      let languageList = null;

      if (!Array.isArray(this.inputLanguage)) {
        languageList = [this.inputLanguage];
      } else {
        languageList = this.inputLanguage;
      }

      // both conditions do stuff with this.el.nativeElement.classList
      if (languageList.includes('ar')) {
        this.addRtl();
      } else {
        this.removeIfRtlExists();
      }
    }
  }
}

以下は、ディレクティブを使用する場所です。「languagesInView」は、@Input() を使用してこのディレクティブを使用するコンポーネントに取り込まれた文字列のリストです ...

<div *ngIf="concept">
  <div class="concept-header" [appRtlView]="languagesInView">
    ...
  </div>
</div>

コンポーネントに渡される languagesInView の入力が変更されると、テンプレートの [appRtlView] に渡す値が変更されることを期待しています。(補間 {{ languagesInView }} を使用して値を画面に出力すると、値が実際に変化することがわかります)

RTLView ディレクティブで ngOnInit を使用すると、「inputLanguage」フィールドへの変更が反映されません。

これを克服するために、ディレクティブで ngOnChanges を使用しています (OnChanges を実装すると、必要なことが実行されます)。

// ngOnInit added because Angular doesn't accept a directive without an OnInit implementation
  ngOnInit() {}

  ngOnChanges(change: SimpleChanges) {
    // TODO: A check to see if the input value has changed or not would help performance
    this.handleRtl();
  }

ディレクティブの初期化に changeDetectionStrategy を追加できませんでした。これにより、ディレクティブは通常 OnChanges を実装することになっていないと思いました。私のオンライン検索はあまり役に立ちませんでした。

Angular ディレクティブで ngOnChanges を実行するのは間違っていますか?

ありがとう

4

2 に答える 2