web-dev-qa-db-ja.com

Angular-@Inputおよび@Outputと注入可能なサービス

親/子コンポーネントの_@Input_/_@Output_の違いはどこにあるのか自分に尋ねていますおよび依存関係で一度だけインスタンス化されるサービスを使用しますInjection@Injectable() 。または、入力/出力以外に違いはありますか?親/子コンプでのみ使用できます。

より良い視覚化のための次の例:

@Inputを使用:

_<parent-comp>
   <child-comp [inputFromParent]="valueFromParent"></child-comp>
</parent-comp>
_

ChildComponent:

_@Component({
  selector: 'child-comp',
  template: ...
})
export class ChildComponent {
  @Input() public inputFromParent: string;
}
_

依存性注入あり

_@Injectable()
export class Service {
   private value: string;

public get value(): string {
   return value;
}

public set value(input): void {
   value = input;
}

}
_

これで、親コンプに値を設定できます。そして、依存性注入で子コンプの値を取得します。 ChildComponent:

_@Component({
  selector: 'child-comp',
  template: ...
})
export class ChildComponent {
  private value: string;
  constructor(private service: Service) {
  this.value = this.service.getValue;
}

}
_

最初のアプローチはよりシンプルに見えますが、親子コンプを通じて3〜4個のプロパティを使用することを認識しました。 _@Input_/_@Output_を使用すると、タンプレットが非常に混乱し、不格好になります。

10
MarcoLe

明確な答えのある質問ではありませんが...

@Input@Outputは、親と子の間の通信が親と子の間だけの場合に役立ちます。 2つのコンポーネント(または深くネストされた祖父母->親->子コンポーネント)のシングルトンデータを維持するサービスを用意しても意味がありません。

また、親が子の変化に対応する必要がある場合にも役立ちます。たとえば、親の関数を呼び出す子コンポーネントのボタンをクリックすると、次のようになります。

<my-child-component (myOutputEmitter)="reactToChildChange($event)"></my-child-component>

そして親で:

reactToChildChange(data: any) {
  // do something with data
}

多くの@Inputプロパティを子に渡していて、テンプレートを整頓したい場合は、入力用のインターフェースを定義して、代わりに渡すことができます。例えば.

export interface MyChildProperties {
   property?: any;
   anotherProperty?: any;
   andAnotherProperty?: any;
}

次に、親から設定された定義を子に渡すことができます。

childProperties: MyChildProperties = {
    property: 'foo',
    anotherProperty: 'bar',
    andAnotherProperty: 'zoob'
}

次に、子コンポーネントは次のようになります。

@Input properties: MyChildProperties;

そしてあなたのテンプレートは次のようになります:

<my-child-component [properties]="childProperties"></my-child-component>

お子様はproperties.propertyproperties.anotherPropertyなどからこれらのプロパティにアクセスできます。

整理整頓されたデータは、通信する必要のあるコンポーネントに含まれています。

ただし、サービスは、複数のコンポーネントがアプリケーション全体のデータの読み取り/書き込みにアクセスする必要がある場合に使用する必要があります。たとえば、現在ログインしているユーザーに多くの異なるコンポーネントがアクセスできるようにする必要があるUserServiceを考えます。この場合、サービスはシングルトンとして適切であるので、ログインユーザーを設定すると、UserServiceを挿入するすべてのコンポーネントがそのデータと関数にアクセスできるようになります。

同様に、変更に対応するためにサービスを使用する場合、コンポーネントがデータの変更をサブスクライブできるように、オブザーバブルでサービスを作成していることに気付くでしょう。上記のように、イベントエミッターはすでに@Outputでこのパターンを提供しています。

単純な親->子の通信の場合、これは不要なオーバーヘッドであり、回避する必要があります。

とはいえ、サービスを使用してグローバルな状態を管理している場合は、 ngrx などの状態管理を使用したほうがよいでしょう。

21
prettyfly