Exploring a new frontend framework for our company's JSF portal, one option being considered is Angular2. The plan is to gradually transition specific components on the page from JSF to Angular2 / REST. The intention is not to utilize Angular2 for routing just yet and only certain components will be shifted to Angular while others remain in JSF for the near future.
The idea is to wrap the content of the body of the JSF template with an Angular root component and project the HTML rendered by JSF into the root component so that the functionality remains the same, allowing all Angular and JSF components to communicate. For example:
<h:body>
<my-app>
<h:panelGroup styleClass="languageSwitcher">
<h:form>
<h:selectOneMenu value="#{languageHandler.language}" onchange="submit()">
<f:selectItem itemValue="en" itemLabel="English" />
<f:selectItem itemValue="nl" itemLabel="Dutch" />
</h:selectOneMenu>
</h:form>
</h:panelGroup>
<my-angular-component data-source="/rest/mydata"></my-angular-component>
</my-app>
<h:body>
In the case of Angular 1, transclusion would have been used to achieve this functionality. However, it seems that Angular 2 content projection has limitations at the root component level as the rendered HTML is not recognized as an Angular-compiled view.
An alternative approach considered was using the root component's templateURL
to fetch the dynamically rendered JSF page, but implementation proved challenging especially due to the multiple POST requests made by JSF.
The proposed solution entails creating a root component for each Angular component that replaces a portion of JSF. This requires executing bootstrap code for every Angular component used on a page. However, this method involves a large amount of boilerplate code and limited communication between Angular components since there isn't a shared root component. Additionally, configuration through attributes requires manual intervention in each component as automatic attribute detection is not supported:
class MyAngularComponent {
constructor(public elementRef: ElementRef) {
this.dataSourceUrl = this.elementRef.nativeElement.getAttribute("data-source");
}
}
Subsequently, when transitioning the entire frontend to Angular, each component must be refactored to use @Input
instead of fetching information from attributes manually.
Are there superior methods to achieve this integration? Or do JSF and Angular2 simply not complement each other well?