Angular에서 동적으로 생성된 구성 요소를 사용하는 경우 필요할 때 상위 구성 요소와 하위 구성 요소 간에 정보를 전달하는 것이 어려울 수 있습니다. 상위 구성 요소에 정보를 제공한 다음 하위 구성 요소 내에 삽입해야 합니다. 반드시 어려운 것은 아니지만 추가 상용구 코드가 많이 발생합니다.
우리가 예전처럼 @Input
데코레이터를 사용할 수 있다면 훨씬 더 좋을 것입니다. 글쎄요? Angular는 버전 16부터 정확히 이와 같은 작업을 지원합니다. 이번 포스팅에서는 그 방법을 알려드리겠습니다. 좋아, 시작해 보자.
먼저, 부모로부터 동적으로 생성된 구성 요소에 데이터를 전달하는 데 사용한 방법을 살펴보겠습니다. 이 예에서는 구성 요소 템플릿 내에 *ngComponentOutlet
있으며 이를 플레이어 구성 요소에 전달합니다.
이 경우에는 사용자 정의 하위 인젝터도 전달하며 이전에 하위 구성 요소에 대한 데이터를 주입한 방법입니다.
@Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; injector: childInjector"></ng-container> ` }) export class App { protected playerComponent = PlayerComponent; }
그리고 이 하위 인젝터를 생성하려면 템플릿 내에서 설정하고 사용할 수 있도록 속성을 생성해야 했습니다.
export class App { protected childInjector?: Injector; ... }
그런 다음 생성자 내의 각도 코어에서 인젝터를 주입해야 했습니다.
export class App { ... constructor(private injector: Injector) { } }
그 후에는 플레이어 토큰을 자식에게 제공하기 위해 create 메서드와 공급자의 배열을 사용하여 자식 인젝터를 설정해야 했습니다.
export class App { ... constructor(private injector: Injector) { this.childInjector = Injector.create({ providers: [ { provide: PlayerToken, useValue: this.player } ], parent: this.injector }); } }
마지막으로, 플레이어 구성 요소인 하위 구성 요소에서 각도 코어의 삽입 방법을 사용하여 플레이어 속성을 설정해야 했습니다.
export class PlayerComponent { protected player?: Player = inject(PlayerToken); }
따라서 이 모든 것은 단순한 플레이어 개체를 동적 구성 요소에 전달하는 것뿐입니다. 즉, 이것이 동적 구성 요소가 아닌 경우 간단히 @Input
으로 만들고 플레이어 데이터 개체를 상위 항목의 @Input
에 바인딩하면 됩니다. 하지만 이는 동적으로 생성된 구성요소이므로 이를 수행할 수 없습니다. 그렇죠?
글쎄, Angular 16부터는 실제로 @Input
을 대신 사용할 수 있으며 지금까지 본 것보다 훨씬 간단합니다.
*ngComponentOutlet
입력 개체를 사용하여 새로운 방식으로 데이터 전달 대신 이 플레이어 속성을 @Input
으로 변경하는 것부터 시작합니다. 그리고 플레이어 인터페이스에 간단히 입력하면 됩니다.
export class PlayerComponent { @Input() player?: Player; }
이제 주입 방법과 플레이어 토큰 가져오기가 더 이상 필요하지 않으므로 제거할 수 있습니다. 그런 다음 상위 템플릿의 템플릿에서 인젝터를 제거하고 대신 입력 개체로 바꿀 수 있습니다. 우리는 이 객체를 원하는 수의 입력에 전달할 수 있습니다. 따라서 5개의 입력이 있는 경우 이름을 포함하고 필요한 데이터를 각각 전달합니다.
하지만 이 경우에는 하위 구성 요소인 플레이어에 대한 입력이 하나만 있으므로 전달하기만 하면 됩니다.
@Component({ selector: 'app-root', template: ` <ng-container *ngComponentOutlet="playerComponent; inputs: { player }"></ng-container> ` })
이제 어린이 주입기를 제거할 수 있습니다. 이는 생성자를 완전히 제거할 수도 있음을 의미합니다. 마지막으로 더 이상 사용하지 않으므로 앵귤러 코어 및 플레이어 토큰 가져오기에서 인젝터를 제거할 수 있습니다.
export class App { protected player: Player = { name: 'LeBron James', games: 1421, points: 38652, fieldGoalPercentage: 0.505, threePointPercentage: 0.345, imageName: 'lebron-james' }; protected playerComponent = PlayerComponent; }
그리고 그게 다야. 우리는 모든 것이 예전처럼 작동하는 것을 볼 수 있습니다. 따라서 실행하기가 훨씬 쉽고 코드도 적어 항상 좋습니다.
하지만 한 가지 아쉬운 점은 @Input
은 지원되지만 @Output
은 지원되지 않는다는 것입니다. 좀 당황스럽지만 그게 바로 그거예요. 이것이 매우 편리하기 때문에 향후 지원을 추가할 수 있기를 바라지만, 기다려 보아야 할 것입니다.
아래 Stackblitz 예제에서 이러한 기술의 데모 코드와 예제를 확인하세요. 질문이나 의견이 있으시면 주저하지 말고 댓글을 남겨주세요.