LoginSignup
2
5

More than 5 years have passed since last update.

angularのDirectiveにおけるHostデコレーターについて

Posted at

formを作るときに何気なく使っているformControlNameですが、ふと本家のソースを読んでみたら、普段使わないような記法が出てきたので調べてみました。

今回はHostデコレーターに注目します。

環境

  • angular 2.3.1
  • angular/material 2.0.0-beta.2

シンプルなフォーム

とりあえずinputが一つあるだけの簡単なフォームを作成します

コード例

simple-form.component.ts
@Component({...})
export class SimpleFormComponent {
  form: FormGroup;

  constructor(
    private fb: FormBuilder
  ) {
    this.form = this.fb.group({
      user: ['default user name'],
    });
  }

  onSubmit() {
    console.log(this.form.value);
  }
}
simple-form.component.html
<md-card>
  <md-card-title>SimpleForm</md-card-title>
  <md-card-content>
    <form [formGroup]="form" novalidate (ngSubmit)="onSubmit()">
      <md-input-container>
        <input mdInput formControlName="user">
      </md-input-container>
      <p>{{ form.get('user').value }}</p>
      <div>
        <button md-button>Submit</button>
      </div>
    </form>
  </md-card-content>
</md-card>

material使っちゃったので見づらいですが、formGroupを作り、userプロパティにformControlがセットされただけのシンプルなフォームです。

formControlNameのソースを見る

執筆時点 https://github.com/angular/angular/blob/bebedfed24d6fbfa492e97f071e1d1b41e411280/packages/forms/src/directives/reactive_directives/form_control_name.ts

constructor(
      @Optional() @Host() @SkipSelf() parent: ControlContainer,

ソースを眺めると、なんとなくformGroupを参照してそうな雰囲気です。

Hostデコレーター

any directive that matches the type between the current element and the Shadow DOM root.

DOMを辿って宣言した型に該当する要素を参照できると。
すごい。なんでもやれそうな気がしてきますね。

formGroupから、特定のformControlを取得するDirectiveを書いてみる

Hostアノテーションを用いることによって、formGroupが取得出来そうなので、formGroupの取得および、指定されたプロパティの値をログに出すようなDirectiveを書いてみます。

コード例

fake-form-control-name.directive.ts
@Directive({
  selector: '[appFakeFormControlName]'
})
export class FakeFormControlNameDirective implements AfterContentInit {
  @Input('appFakeFormControlName') appFakeFormControlName: string;
  private parent: FormGroupDirective;

  constructor(
    @Host() parent: FormGroupDirective
  ) {
    this.parent = parent;
  }

  ngAfterContentInit() {
    console.log(
      this.parent.form.get(this.appFakeFormControlName).value
    );
  }
}

この状態で動かすと、コンソールに 'default user name' が流れるのが確認できました :raised_hand:

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5