web-dev-qa-db-ja.com

@Componentデコレータは正確に何をしますか?

から 公式ドキュメント 私たちはそれを知っています

コンポーネントデコレータを使用すると、クラスをAngularコンポーネントとしてマークし、実行時にコンポーネントを処理、インスタンス化、および使用する方法を決定する追加のメタデータを提供できます。

しかし、私はさらに深く掘り下げて、追加のメタデータを提供することを除いて、コンポーネントデコレータが実際に何をするのかを理解したいと思います。

ソースコードを調べたところ、すべてのデコレータが makeDecorator 関数を使用して作成されていることがわかりました。そしてここで私は迷子になりました。たとえば、ComponentデコレータとngModuleデコレータの違いはどこにありますか?彼らは同じことをしていますか?そうは思わないでください。

答えのように、makeDecorator関数を使用せずにコンポーネントデコレータを再作成するために何をすべきかを段階的に説明しておくと便利です。

[〜#〜] upd [〜#〜]:そして、もちろん、TypeScriptデコレータがどのように機能するかは知っています。

7
Stepan Suvorov

しかし、追加のメタデータを提供することを除いて、コンポーネントデコレータが実際に何をするのかをより深く理解したいと思います。

なぜそれ以上のものが必要なのですか? @Componentデコレータ関数に渡される引数はコンポーネントmetatdataであると言われています。つまり、メタデータを提供することが主な責任です。

似たようなものを再現したい場合の最も簡単な方法は、

  1. reflect-metadata をインストールします。

    npm install --save reflect-metadata
    
  2. デコレータ関数を作成する1

    import 'reflect-metadata';
    
    interface MyComponentMetadata {
      template?: string;
      selector?: string;
    }
    
    function MyComponent(metadata: MyComponentMetadata) {
      return function(ctor: Function) {
        // add metadata to constructor
        Reflect.defineMetadata('annotations', metadata, ctor);
      }
    }
    
  3. これを使って

    @MyComponent({
      selector: 'component',
      template: '<hello></hello>'
    })
    class HelloComponent {
    }
    
  4. メタデータを取得する必要がある場合は、

    let metadata = Reflect.getMetadata('annotations', HelloComponent);
    

メタデータの目的は、Angularがクラスをどうするかを知るための情報を提供することです。したがって、デコレータは単なるメタデータプロバイダー以上のものである必要はありません。Angularは、デコレータ関数ではなく、メタデータをどう処理するかを決定します。


1デコレータに関するTypeScriptドキュメント を参照してください。

8
Paul Samsotha