GWT Widgets integration
There are two ways envisaging integrating a legacy GWT widgets with Angular 2 components. One consist in reusing legacy widgets into a new Angular2Boot application. The other is to integrate Angular 2 components inside an existing Widget based GWT application. Both ways are possible with Angular2Boot, and this document helps you to realize each of them.
- GWT Widgets integration
- Angular 2 components inside a Widget based GWT application
- Widgets inside an Angular2Boot application
Angular 2 components inside a Widget based GWT application
You may want to benefit from the functionalities brought by Angular2Boot in your legacy GWT application, after all double data binding is not so bad ;) !
An sample project demonstrating this possibility is available at this address: https://github.com/ltearno/angular2boot-demos/tree/master/widgets-integration-wayback.
In this case you have a few steps to follow:
Import Angular2Boot integration artifact
Import the Maven artifact containing all the integration stuff:
Provide an Angular module
Write an Angular Module class with your components and imports. The bootstrap component should be set to
AngularIntegrationShellComponent, which is provided by
Initialize the integration layer
Before you need to integrate Angular 2 components in your application, you must make this call (this could be in you application
Create Angular 2 components and insert them
The returned object is a GWT widget that can be inserted anywhere in the normal widget tree. The sample application inserts it inside a regular
Instances of the
AngularComponentContainerWidget<T> class provide some useful methods:
Widgets inside an Angular2Boot application
You may want to integrate legacy GWT widgets in your new Angular application. Maybe because you are in the process of migrating all your widgets and you have not yet completely finished, or you have a legacy widget with a big business value and you don’t want to reimplement it, or any reason…
It is possible to integrate widgets in a Angular2Boot project.
NOTE The following tutorial’s code can be found on github at this address github.com/ltearno/widgets-integration.
NOTE You must use at least the
1.6 version of
angular2gwt-integration libraries in your project. If you don’t, you won’t get the
WidgetAdapterPanel class needed to integrate with legacy widgets.
Suppose you have a list of a certain DTO (
Product in this example). You want to display a master/detail UI allowing the user to edit each
Product of the list. Let’s say also that you want the list to be implemented with a normal Angular component (with data binding and so on), and you want to reuse the Product edition form which you have already developped with previous versions of GWT (
The application will have its root
ApplicationComponent component and two more :
ProductsComponent to display the list and
ProductComponent to edit the selected product (which is using the legacy GWT widget). The legacy widget that we import is called
ProductForm, it implements the
The legacy widget. In this example it is very simple but you can imagine almost whatever widget your want.
Here is the bootstrap component of our application:
<products></products> element triggers the
ProductsComponent which we’ll see just now.
There is nothing special in this component. The
products array is used in the template to populate
<li> elements (one for each product). When a
<li> is clicked, the
select() method is called, which updates the
This attribute is tracked in the template. Look at the following line :
selectedProduct attribute is valid, a
<product> element is added which is selected by the
ProductComponent class that we’ll examine just after. This component is given the selected product in his input with the part:
This is the component that integrates with GWT widgets. Here is the implementation:
- Get the DOM element of our insertion point in the component’s template,
- Create a
WidgetAdapterPanelwidget that wraps around the DOM element,
- Insert your legacy UI in the
- Take care of memory leaks by cleaning up when the component is destroyed.
Get the DOM element from the component’s template
In the template we use the named reference
#panel to name the insertion point.
We then get the corresponding DOM element by inserting an
ElementRef attribute with a
@ViewChild annotation indicates to Angular that we want it to inject the DOM element into our component.
During the component creation lifecycle, after the template for the component is created, the
ElementRef panelElement attribute is injected by Angular with the correct DOM element. Angular then calls the
ngAfterViewInit method of our component to let us take the appropriate actions.
WidgetAdapterPanel widget that wraps around the DOM element
ngAfterViewInit method we first create our UI and then comes the most important action:
WidgetAdapterPanel widget is created. This widgets serves as a bridge between Angular and legacy Widgets. Its constructor takes an
ElementRef as the only parameter and use it to insert Widgets inside.
We give the
ElementRef to the constructor so that GWT widgets are inserted in the appropriate div.
Insert your legacy UI in the
And we then insert our GWT UI (the
vp widget) in the adapter panel.
Our UI contains an instance of the
ProductForm class which is the legacy widget that we want to integrate to the application.
Integrating with Angular data binding
The component is of no use if it cannot be used by other components. We create an
@Input property to receive the
Person our component should display and edit.
Since we need to take action when the input is intercepted (we will update the Person form widget), we will use a property getter and setter pair:
@Input annotation tells Angular that we want our
setProduct method to be called when the component’s input “product” changes. The
setProduct method is called with the new value of the input.
We will take this opportunity to update the GWT widget
form with the updated data.
getProduct method is automatically used by Angular to retreive the value of our
product property, so we return the value of our internal
Taking care of memory leaks
In order to clean up correctly our component when it is destroyed, we need to add the following method to our component:
We saw a way to integrate legacy GWT widgets inside an Angular 2 application !