AngularのProjectにDialogっていうディレクトリ構成を入れる理由
2022年7月現在、Angularを2つの企業で開発しています。
pages, layoutsディレクトリを追加した記事の延長としてもう一つのviewに関するdirectoryとして、Projectの性質に応じてdialogsというディレクトリを追加している理由を記載しようかと思い記事に記載します。
TL;DR
dialogディレクトリを作成する理由は2つ。
1つ目は、dialogのよびだしまたは、閉じる際にdialogにまつわる情報で必要なものは、DialogId
とDialogComponent
になるので、両方を同一のDirectory(またはFile)内部で管理をする。
2つ目は、現状のdirectory構成がpresentational-component
、container-component
になるため呼び出しもとでcontainer or presentational
なのかの意識をもたない設計を実施したい。
の2つの理由で採用する時がある。(container/presentationalは、現状の最適解ではないのは理解していますが、design systemを持たず、のりで開発をするCDRはスタートしたプロジェクトでA以降壊滅する光景をみてきいるので、序盤戦の開発はcontainer.presentaional推しです)
table of contents
- dialog directoryを扱う前に
- dialogs directoryを作成理由
- dialgos directoryの性質
0. dialog directoryを扱う前に
2022年7月現在、Angularを利用して2つの企業のAppliationを開発しています。
利用しているLibraryは,ngrx, nx(nrwl), angular/component(material)を中心に開発をしています。
基本のディレクトリ設計は、下です。また、Atomic DesignでいうAtom, Molecules相当なものはAngularComponentまたは、nx libに切り出して開発を実施しているケースが多いです。
feature-module
|- components
|- containers // NOT angular default
|- { reducers, actions, effects, resolvers, guards }
|- { pages, layouts } // NOT angular default
|- feature{.routing}.module.ts
今回、話をするdialog
は下のようなディレクトリ設計を意図しています。
feature-modules
|- components
|- containers // NOT angular default
|- dialogs // dialos directory
|- { reducers, actions, effects, resolvers, guards }
|- { pages, layouts } // NOT angular default
|- feature{.routing}.module.ts
1. dialog directoryを作成理由
1. dialogにまつわる情報をカプセル化させたかった
2. 呼び出し元が参照する際に、dialogの性質によって変更されるディレクトリを意識させたくなかった
dialog directoryを作成した理由としては、2つあります。
1つ目は、dialogの呼び出しまたは、閉じる際にdialogにまつわる必要な情報は、DialogId
とDialogComponent
になるので、両方を同一のDirectory(またはFile)内部で管理を実施したい。
2つ目は現状のProjectで採用しているdirectory設計がcontainer-component
、presentational-component
になるので、dialogの性質によって呼び出し元がcontainer
なのか、component
なのかを気にしたくないのが理由です。
1-1. dialogにまつわる情報をカプセル化させたかった
effects、containers、component-store、service
でdialogを扱う(開く、閉じる)際に利用したい情報としては、DialogComponent
、DialogId
(refもあるが、、、)の2つの情報がメインになるため、DialogId
とDialogComponent
を同一のディレクトリまたは、ファイルでカプセル化を実施し、Dialogにまつわる関心ごとを集約させたかったため、以下のディレクトリ構成を作成した。
feature/dialogs
|- foo-dialog
|- foo-dialog.component{.spec}.ts
|- foo-dialog.component.html
|- foo-dialog.component.scss
// imports
export cosnt FOO_DIALOG_ID = `${MODULE_NAME}:FooDialog`
@Component()
export class FooDialog {}
feature/dialogs/foo-dialog.component.ts
をimportすれば、DialogIDを同時に扱うことができるため、FooDialog
にまつわる情報を集約的に扱うことができる。(index.tsを加えてもServiceを加えてもfoo-dialog
というディレクトリ内部で完結することができる。)
2. 呼び出し元が参照する際に、dialogの性質によって変更されるディレクトリを意識させたくなかった
{presentational, container}-component
を採用しているため、
- data(store)にまつわる情報を利用する際に、
container-components
- viewだけの情報を利用する際に、
presentational-components
になるためdialogの性質よりcontainer directory
にいれるか、component directory
にいれるかの判断や変更の必要性が生じていた(auto importすればいいけど気持ち悪い)。
利用する側がcontainer
、components
の関心を持つことにメリットが開発の側面から薄かったため、この関心を意識させないようなディレクトリ構造を作成したかった。
上記2つの理由をもとにdialog directory
の作成をする場合がある。。。
2. dialgos directoryの性質
dialog-directoryは、dialogID
と@Component
を保持することを制約におきました。
また、presetatinal,container
のどちらでも利用可能としました(dialogの性質上どちらもあり得る)。
また、呼び出し元ではafterClosed
を利用せずに、データの作成や編集、削除などでは、dialogで状態を管理できるように、Service(component-store)を利用して関心の分離をはかる。
制約
- dialogIdと@Componentをexportする
- 可能な限りdialogにまつわる状態は、dialog内部で完結をする(component-store, serviceを推奨)
- afterClosed, afterOpendを利用してstoreの更新は実施しない
憂慮
- presentational-component, container-componentも可
- consts.tsで,`dialogId`や`dialogConfig`をexportして対応も可
特性
- dialog内部の関心はdialog内部で実施する
- dialogにまつわる情報は、directory内部で管理を実施する
例
1. ベース構成
feature/dialogs
|- foo-dialog
|- foo-dialog.component{.spec}.ts
|- foo-dialog.component.html
|- foo-dialog.component.scss
2. constを利用したファイル構成
feature/dialogs
|- foo-dialog
|- foo-dialog.component{.spec}.ts
|- foo-dialog.component.html
|- foo-dialog.component.scss
|- foo-dialog.config.ts
export const FOO_DIALOG_ID = `${MODULE_NAME}:FooDialog`
export const FOO_DIALOG_CONFIG = {}
3. index.tsを利用したexport管理
feature/dialogs
|- foo-dialog
|- foo-dialog.component{.spec}.ts
|- foo-dialog.component.html
|- foo-dialog.component.scss
|- foo-dialog.config.ts
|- index.ts
export { FooDialog } from "./foo-dialog.components.ts"
export { FOO_DIALOG_ID, FOO_DIALOG_CONFIG } from "./foo-dialog.config"
記載はしませんが、dialogがかなりFatな場合は、libとかmoduleに切り出して、Openなど管理するServiceを突っ込むこともありますが、その際にはデザイナーに「マジ!?」ってわざとらしくききます。
Discussion