Using a multi-value component, we'll explore how you can write a component that renders multiple metrics from an Internet of Things device in a room using Kendo UI Builder.
In the previous blog of my Kendo UI Builder series, I showed you how to render a single metric obtained from a REST service. Today, I'll demonstrate how write a component that renders multiple metrics from an Internet of Things device in a room. The data from the various rooms and devices is obtained via a REST data provider.
This sample will show us the difference between single-value and multi-value components via usage of the Value Primitive property in the component definition file.
If you have not read the blog on how to use a single-value component, now’s the time to do so to ensure you have the proper context.
The view containing the combo-box and the custom component looks like this:
To follow along, download the template samples zip from github or clone the repository https://github.com/thierryciot/kendoui-builder-template-samples; open folder components/custom-device-multiple-metrics-comp and follow the same step outlined in this post to install this template in your target application.
We need:
For both, please check the detailed instructions in the prerequisites section of this blog.
Note: You can reuse the application and blank view from the previous blog. Simply drag the multiple metrics custom component to a separate row.
Open the file components/custom-device-metrics-comp/custom-device-multiple-metrics-comp.json.
The main difference with the single-value device metric component is that the valuePrimitive property is defined as false and we define the dataSourceName property:
01.
"valuePrimitive"
: {
02.
"type"
:
"boolean"
,
03.
"default"
:
false
,
04.
"hidden"
:
true
,
05.
"order"
: 3
06.
},
07.
08.
"dataSourceName"
: {
09.
"type"
:
"string"
,
10.
"default"
:
""
,
11.
"hidden"
:
true
,
12.
"order"
: 4
13.
},
When valuePrimitive is false, the full model is made available in the EJS expression <%-model%>, for example, dataSourceModel1. When valuePrimitive is true, as we saw in the previous blog, <%- model %> resolves to the model name and the field name, for example, dataSourceModel1.hum
Here is how the property panel renders:
Additionally, to get multi-value working, the Kendo UI Builder code generator needs the dataSourceName, so we define it as a hidden property.
See file components/custom-device-multiple-metrics-comp/design-time/template.html.ejs.
We simply output a list of all the metrics with hard-coded values to give the user a sense of the overall aspect:
<
ul
style
=
"padding-left: 1.5rem;"
>
<
li
>Current Temperature: 23</
li
>
<
li
>Set Temperature: 22</
li
>
<
li
>Humidity: 65%</
li
>
<
li
>CO2: 145</
li
>
<
li
>VOC: 50</
li
>
</
ul
>
See file components/custom-device-multiple-metrics-comp/angular/template.html.ejs:
<% if ( model === "" ) { %>
<
div
>Please select a model to use this component.</
div
>
<% } else { %>
<
div
style
=
"margin-top: 1rem;"
>
{{$config.components.<%-id%>.metric}}:
<
ul
style
=
"margin-top: 0.8rem; padding-left: 1.5rem;"
>
<
li
style
=
"margin-top: 0.6rem;"
>
Current Temperature: {{$dataModels.<%- model %>.currentTemp}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
Set Temperature: {{$dataModels.<%- model %>.setTemp}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
Humidity: {{$dataModels.<%- model %>.hum}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
CO2: {{$dataModels.<%- model %>.co2}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
VOC: {{$dataModels.<%- model %>.voc}}
</
li
>
</
ul
>
</
div
>
We simply output a list of metrics. The data is obtained starting at $dataModels. This is defined in the generated code base component TypeScript file, for example, devices.view.base.component.ts. Note: the name can vary as it depends on how you name your view but the file suffix will be the same.
It is an object literal with a reference to an object containing the field values we want to render in component instances, for example:
public $dataModels: any = {
DevicesModel:
new
IoTDevice()
};
The IoTDevice class was auto-generated and looks like this:
export class IoTDevice {
public id: number;
public room: string;
public setTemp: number;
public currentTemp: number;
public hum: number;
public co2: number;
public voc: number;
}
See file components/custom-device-multiple-metrics-comp/angularjs/directive.html.ejs.
Here again, we output a list of metrics:
<%#
$viewModels is defined at the view level - see generated code in app\src\modules\custom-components\room-metrics\controller.js
%>
<
ul
style
=
"padding-left: 1.5rem;"
>
<
li
style
=
"margin-top: 0.6rem;"
>
Current Temperature: {{vm.$viewModels.<%-model%>.currentTemp}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
Set Temperature: {{vm.$viewModels.<%-model%>.setTemp}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
Humidity: {{vm.$viewModels.<%-model%>.hum}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
CO2: {{vm.$viewModels.<%-model%>.co2}}
</
li
>
<
li
style
=
"margin-top: 0.6rem;"
>
VOC: {{vm.$viewModels.<%-model%>.voc}}
</
li
>
</
ul
>
The generated code (app\src\modules\custom-components\room-metrics\controller.js) defines $viewModels as an array of data source models. The expression vm.$viewModels.<%-model%> will be translated by EJS compiler to vm.$viewModels.DevicesModel. From there, we can simply access all the metrics we need.
To write components that use multiple values from a data source, we need to define the “Value Primitive” property as false. This has an impact on the code generation process and in particular how the model is defined. Here is a summary of the syntax to access metrics depending on the valuePrimitive setting:
valuePrimitive=false
valuePrimitive=true
We now have learned how to create components that interact with the model defined at view level. In a future blog, we will see how to apply these skills to create a view where we can select a travel destination and show its name, rating and a map. As usual, stay tuned! 😊
If you jumped into this series in the middle and want to start from the beginning, you can find the previous blog posts here:
Thierry Ciot is a Software Architect on the Corticon Business Rule Management System. Ciot has gained broad experience in the development of products ranging from development tools to production monitoring systems. He is now focusing on bringing Business Rule Management to Javascript and in particular to the serverless world where Corticon will shine. He holds two patents in the memory management space.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites