-
Notifications
You must be signed in to change notification settings - Fork 21
quick bridge developer's tutorial
This document explains the basic structure of the Syncfusion bridge (implemented as a typical Aurelia plugin) by defining the process of adding the simplest fictitious ej-widget called click-counter
shown below:
Image 1
Note the Image 1 shows the initial temporary UI for the Aurelia Syncfusion bridge's Catalog application which will be used until all ej
widgets needed to render the complete Catalog's User Interface become available as Aurelia Components, implemented in the Syncfusion bridge. At that time the Catalog application will be similar to this (KendoUI version)
Image 2
Image 3
As Image 3 depicts, the Aurelia Syncfusion bridge is a composite application consisting of two main parts:
- The bridge - which contains all of the code needed to "convert" native ej widgets to Aurelia components. All of the bridge code is contained in this folder
Image 4
- The catalog - which renders all of the Aurelia ej components exported by the bridge. All of the catalog code is contained in this folder.
Image 5
Each widget wrapper consists of at least one file - JavaScript class that implements the widget. There is also an optional html file.
In this document we will create the src/clickcounter folder
with the following content
import {customElement} from 'aurelia-templating';
import {constants} from '../common/constants';
@customElement(`${constants.elementPrefix}click-counter`)
export class ClickCounter {
count = 0;
increment() {
this.count++;
}
}
Note that this code defines the clickcounter Aurelia component as a custom element
.
Image 6
Hints:
useAll()
method returns the list of all widgets that need to be wrapped. This list consists of a single clickounter.js
JavaScript class.
Define Syncfusion bridge global constants
:
export const constants = {
eventPrefix: 'ej-on',
bindablePrefix: 'ej-',
attributePrefix: 'ej-',
elementPrefix: 'ej-'
};
2. Adding clickcounter
component to the catalog
application.
Image 7 below is an expanded view of the Image 5 - presenting more details of the catalog application's structure:
Image 7
Step 2.1 Add sample/src/samples/click-counter
folder
This folder should have the following files
2.1.1 basic-use.html
<template>
<div>
<div>
<div>
<h4>Basic Click control</h4>
<ej-click-counter></ej-click-counter>
</div>
</div>
</div>
</template>
2.1.2 basic-use.js
export class BasicUse {}
2.1.3 index.js
import {useView, inject} from 'aurelia-framework';
import {Registry} from 'shared/registry';
@useView('shared/showcase.html')
@inject(Registry)
export class Index {
constructor(registry) {
this.registry = registry;
}
configureRouter(config, router) {
this.router = router;
return this.registry.load(config, 'click-counter');
}
}
2.1.4 registry.json
{
"title": "Click counter",
"samples": {
"basic-use": {
"default" : true,
"files": ["html", "js"]
}
}
}
Step 2.2 Add sample/src/samples
folder with page rendering infrastructure
<template>
<require from="./menu"></require>
<menu router.bind="router"></menu>
<router-view></router-view>
</template>
import {inject} from 'aurelia-framework';
import {Registry} from 'shared/registry';
import { ComponentService } from '../shared/component-service';
@inject(Registry, ComponentService)
export class Index {
constructor(registry, componentService) {
this.registry = registry;
this.componentService = componentService;
this.routerConfig = componentService.getRouterConfig(true);
}
configureRouter(config, router) {
config.title = 'Samples';
// config.map([
// { name: 'default', route: '', redirect: 'click-counter' },
// { name: 'click-counter', route: 'click-counter', moduleId: './click-counter/index', title: 'Click-counter' },
// { name: 'navbar', route: 'navbar', moduleId: './navbar/index', title: 'Navbar' },
// { name: 'navs', route: 'navs', moduleId: './navs/index', title: 'Navs' },
// { name: 'button', route: 'button', moduleId: './button/index', title: 'Button' },
// { name: 'collapse', route: 'collapse', moduleId: './collapse/index', title: 'Collapse' },
// { name: 'panel', route: 'panel', moduleId: './panel/index', title: 'Panel' }
// ]);
this.routerConfig.unshift({ name: 'default', route: '', redirect: 'click-counter' });
config.map(this.routerConfig);
this.router = router;
}
}
<template>
<div class="btn-group" role="group">
<div repeat.for="category of categories" class="btn-group">
<button class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
${category.title}<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li repeat.for="ctrl of category.controls">
<a href.bind="ctrl.link">${ ctrl.title }</a>
</li>
</ul>
</div>
</div>
</template>
import {inject, bindable} from 'aurelia-framework';
import {DOM} from 'aurelia-pal';
import { ComponentService } from '../shared/component-service';
import json from './menu.json!';
@inject(Element, ComponentService)
export class Menu {
@bindable router;
constructor(element, componentService) {
this.categories = componentService.getIterableComponents(true);
this.element = element;
this.componentService = componentService;
}
attached() {
// this.generateRow(json);
}
generateRow(data) {
let div = DOM.createElement('div');
div.className = 'btn-group';
div.setAttribute('role', 'group');
this.element.appendChild(div);
for (let key of Object.keys(data)) {
let buttonDiv = DOM.createElement('div');
buttonDiv.className = 'btn-group';
buttonDiv.setAttribute('role', 'group');
let button = DOM.createElement('button');
button.className = 'btn btn-default dropdown-toggle';
button.setAttribute('data-toggle', 'dropdown');
button.setAttribute('aria-haspopup', 'true');
button.setAttribute('aria-expanded', 'false');
button.innerHTML = key + ' <span class="caret"></span>';
buttonDiv.appendChild(button);
let ulItem = DOM.createElement('ul');
ulItem.className = 'dropdown-menu';
for (let subNav of Object.keys(data[key])) {
let liItem = DOM.createElement('li');
let aItem = DOM.createElement('a');
aItem.setAttribute('href', `#/samples/${data[key][subNav]}`);
aItem.innerHTML = subNav;
liItem.appendChild(aItem);
ulItem.appendChild(liItem);
}
buttonDiv.appendChild(ulItem);
div.appendChild(buttonDiv);
}
}
}
{
"Most popular": {
"Click counter": "click-counter"
}
}
Note: the above file will have to be changed for each newly added wrapper and component - it is the initial component chooser used to select a few initially implement components.
Step 2.3 Add sample/src/samples/shared
folder with page rendering infrastructure
Note: at this time we will consider the content of this folder finished and will return to its content description only if something needs to be changed later.
Step 2.4 Observe sample/src/samples/
folder with application rendering infrastructure
Note: at this time we will consider the content of this folder finished and will return to its content description only if something needs to be changed later.
Since this application follows the es2016 application skeleton structure specification it should be built and run as described in this README.md file. Specifically, having all tooling installed, you simply type
gulp watch
after setting your console's current directory to the root of the local clone of the aurelia-syncfusion-bridge repository as shown below:
C:\work\aurelia-ui-toolkits\Syncfusion\aurelia-syncfusion-bridge (master)
λ ls
LICENSE build devbuild jspm_packages node_modules sample test
README.md config.js gulpfile.js karma.conf.js package.json src wallaby.js
C:\work\aurelia-ui-toolkits\Syncfusion\aurelia-syncfusion-bridge (master)
λ gulp watch