Angular 2 Can Do Kendo Too!
Michael K. Snead
Angular2Kendo:
Topic of Discussion
- Create an Angular 2.0 Component
- ...without a custom element
- Injecting the native DOM element
- Hooking up to the Angular 2.0 lifecycle
- Create/destroy/update kendo widgets
- Render Component children
Integrating frameworks isn't actually that hard...
Building with Angular 2: Tools
- Visual Studio 2015
(Web Storm 11 is 'da bomb' though!) - WebPack
(module loader/bundler) - Babel
(transpile)
Bundle.js
A single entry-point (usually 'app.js') begins the tree of dependencies, which node-based webpack includes in the bundle.
Babel converts ES-next (ES6+) to ES-today
'import' statements become CommonJS 'require' that node.js understands
ES*
ES*
ES*
CJS
CJS
CJS
Create A Component
import { Component, View } from 'angular2/angular2';
/* Using this element would be something like ...
template: `
<div>Hey, this is a cool app!</div>
<div><kendocomponent widgetname="Foo!"></kendocomponent></div>
`
*/
@Component({
selector: 'kendocomponent',
inputs: ['widgetname'],
//outputs: [...], <- if we had events, like our own 'onChange'
})
@View({ template: '<span>You told me it was {{widgetname}}</span>' })
export class KendoComponent { }
No custom element
import { Component, View } from 'angular2/angular2';
/* Using this element would be something like ...
template: `
<div>Hey, this is a cool app!</div>
<div><p data-role="kendocomponent" widgetname="Foo!"></p></div>
`
*/
@Component({
selector: '[data-role=kendocomponent]',
inputs: ['widgetname'],
//outputs: [...], <- if we had events, like our own 'onChange'
})
@View({ template: '<span>You told me it was {{widgetname}}</span>' })
export class KendoComponent { }
Inject native DOM element
import { Component, View, ElementRef } from 'angular2/angular2';
@Component({
selector: '[data-role=kendocomponent]',
inputs: ['widgetname']
})
@View({ template: '<span>You told me it was {{widgetname}}</span>' })
export class KendoComponent {
static get parameters() {
return [[ElementRef]];
}
constructor(elementRef) {
var domElement = elementRef.nativeElement;
$(domElement).attr('style', 'background-color: blue;');
}
}
Hook up lifecycle
import { Component, View, ElementRef } from 'angular2/angular2';
@Component({
selector: '[data-role=kendocomponent]',
inputs: ['widgetname'],
bindings: [ElementRef]
})
@View({ template: '<span>You told me it was {{widgetname}}</span>' })
export class KendoComponent {
static get parameters() {
return [[ElementRef]];
}
constructor(elementRef) {
// Fires one time when component instantiated
console.log("Hey, I'm constructed! widgetname is", this.widgetname);
var domElement = elementRef.nativeElement;
$(domElement).attr('style', 'background-color: blue;');
}
onInit() {
// Fires one time at the beginning
console.log("Hey, I'm initialized! widgetname is", this.widgetname);
}
onChanges(changes) {
// Fires once in the beginning and whenever bindings are updated
console.log("Hey, I'm changing! widgetname is", this.widgetname);
}
onDestroy() {
// Fired when the component is to be disposed of
console.log("Hey, I'm being destroyed! It's quite painful ...");
}
}
CRUD the Kendo Widget
import { Component, View, ElementRef } from 'angular2/angular2';
@Component({
selector: '[data-role=kendocomponent]',
inputs: ['widgetname', 'bound'], // we want a new binding to send arguments to kendo
bindings: [ElementRef]
})
@View({ template: '' }) //We want an empty template, kendo will fill it
export class KendoComponent {
static get parameters() {
return [[ElementRef]];
}
constructor(elementRef) {
this.domElement = elementRef.nativeElement;
this.initialized = false;
}
onInit() {}
onChanges(changes) {
if(!this.initialized) { this.init(); this.initialized = true; }
if(changes.bound) { //if the 'bound' binding changed...
$(this.domElement).data('kendo' + this.widgetname).value(changes.bound.currentValue.value);
}
}
init() {
$(this.domElement)['kendo' + this.widgetname](this.bound);
}
onDestroy() {
$(this.domElement).data('kendo' + this.widgetname).destroy();
$(this.domElement).empty();
}
}
Render children
import { Component, View, ElementRef } from 'angular2/angular2';
@Component({
selector: '[data-role=kendocomponent]',
inputs: ['widgetname', 'bound'], // we want a new binding to send arguments to kendo
bindings: [ElementRef]
})
@View({ template: '<ng-content></ng-content>' }) //Tell Angular 2 to render children
export class KendoComponent {
static get parameters() {
return [[ElementRef]];
}
constructor(elementRef) {
this.domElement = elementRef.nativeElement;
this.initialized = false;
}
onInit() {}
onChanges(changes) {
if(!this.initialized) { this.init(); this.initialized = true; }
if(changes.bound) { //if the 'bound' binding changed...
$(this.domElement).data('kendo' + this.widgetname).value(changes.bound.currentValue.value);
}
}
init() {
$(this.domElement)['kendo' + this.widgetname](this.bound);
}
onDestroy() {
$(this.domElement).data('kendo' + this.widgetname).destroy();
$(this.domElement).empty();
}
}
Next steps...
- Make bound properties dynamic
- Make specific components + selectors for each Kendo widget
(ie: DatePicker, DropDownList, Grid, Editor) - etc...
Further reading ...
- Anything before 10/3/2015 is probably out-of-date
https://github.com/angular/angular/blob/master/CHANGELOG.md - Victor Savkin's blog (Software Engineer at Google) (Updated 10/12)
http://victorsavkin.com/post/118372404541/the-core-concepts-of-angular-2 - Thoughtram Blog - View Encapsulation in Angular 2 (Updated 10/25)
http://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html -
5 minute quick start
https://angular.io/docs/js/latest/quickstart.html
Get to know...
ECMAScript 6 and 7 (ES2015, ES2016)
What browsers support ES6 and ES7?
https://kangax.github.io/compat-table/es6/
ES6 Features
https://github.com/lukehoban/es6features
Try ES-next in your browser
https://babeljs.io/repl/
ECMAScript 6 - New Features: Overview & Comparison
http://es6-features.org/
Taming the asynchronous beast with ES7
http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html
JavaScript Decorators
https://github.com/wycats/javascript-decorators
ECMAScript 6 modules: the final syntax
http://www.2ality.com/2014/09/es6-modules-final.html
Questions?
Thanks for your time.
Angular 2 Can Do Kendo Too
By Michael Snead
Angular 2 Can Do Kendo Too
Illustrate how to create Angular 2 components that wrap Kendo UI widgets.
- 5,526