DEV Community

Ahmed Elharouny
Ahmed Elharouny

Posted on • Originally published at Medium on

Introducing xcomponent support for angular 2+

For more information about xcomponent framework itself or how to create components please check this post by Daniel Brain

Angular2 driver

With version 3.0.0 of xcomponent, its now easier than ever to embed xcomponents into your angular apps by utilizing the new angular2 driver. Using the driver will enable xcomponent to integrate with angular specific concepts such as input bindings and change detection cycle which results in a better and more predictable experience.

Usage example

Given that inside an angular app we want to use a login component that is declared as:

(login.js)

window.MyLoginXComponent = xcomponent.create({
 tag: 'my-login-component',
 url: 'http://www.component.com/login.htm',
 props: {
 prefilledEmail: {
 type: 'string',
 required: false
 },
 onLogin: {
 type: 'function',
 required: true
 }
 }
});

The first step is to make sure that component script is loaded into current page:

(index.html)

<script src="http://www.component.com/login.js"\></script\>

Then we need to register angular2 driver and get a reference to the angular module that holds the component:

(my-login-xcomponent-module.ts)

import * as ngCore from '@angular/core';
declare const MyLoginXComponent:any;
export const MyLoginXComponentModule = MyLoginXComponent.driver('angular2', ngCore);

Then import that module into any module where you want to use the component:

(app-module.ts)

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app-component';
import { MyLoginXComponentModule } from './my-login-xcomponent-module';

@NgModule({

imports: [BrowserModule, MyLoginXComponentModule],
 declarations: [AppComponent],
 bootstrap: [AppComponent]
})

export class AppModule {
 constructor () {
 }
}

Now we can use the component the same way we would use any other component in the app:

(app-component.html)

<my-login-component [props]="{ onLogin: onLogin, prefilledEmail: prefilledEmail }"/>

(app-component.ts)

import { Component } from '@angular/core';

@Component({
 selector: 'my-app',
 templateUrl:'./app-component.html',
})
export class AppComponent {
 prefilledEmail:string;
 email:string;
 constructor() {
 this.prefilledEmail = 'foo@bar.com';
 this.onLogin = this.onLogin.bind(this);
 }
 public onLogin (email){
 this.email = email;
 }
}

A complete example code can be fond at the following URLs:

Things to notice:

  • In order to register the angular2 driver we need to pass all functions exported by “@angular/core” module. That is to make sure that you don’t have to update your code if we later on decided to use another angular core function. You can get access to an object that has all exported functions using “import * as” technique.
import * as ngCore from '@angular/core';
  • Alternatively you can still only pass functions that is used by angular2 driver at the moment
import { Component, NgModule, ElementRef, NgZone } from '@angular/core';

declare const MyLoginXComponent:any;
export const MyLoginXComponentModule = MyLoginXComponent.driver('angular2', { Component, NgModule, ElementRef, NgZone } );
  • The contract for the wrapping angular component is identical to the contract for creating the xcomponent or rendering it manually; one “props” input binding where we can add properties and functions expected by the underlying xcomponent.
  • Because functions will be called from xcomponent on another context and potentially another domain we need to make sure we “bind” the function back to “this” (the class) as by default it will be bound to the xcomponent instance itself. This will make sure we can safely use “this” inside “onLogin” function to refer to the component class as we expect.
this.onLogin = this.onLogin.bind(this);

We are very excited about this feature as it allows along with other drivers like react, angularJs and glimmer for a seamless integration with components written in different technologies and hosted on different domains.

Feel free to reach out if you have any questions. And please report any issues to xcomponent repository on github.

Top comments (0)