Bind Checked State to Custom Model Fields
By design, the TreeView does not support custom checkbox binding.
While, as a result, the AngularJS scope model field ($scope.treeData
) does not get updated, the TreeView updates its own Data Source instance. To programmatically update the AngularJS scope model field, assign the checked state of the TreeView Data Source to the scope model field. Alternatively, you can use the TreeView Data Source. The TreeView is then initialized as a Kendo UI component, loads its own Data Source, and the AngularJS bindings are applied consequently. Therefore, to update the ng-model
within the template, assign ng-model=dataItem.customField
.
For large data sets, it is not recommended to bind the checked state to an AngularJS
$scope
model field because performance recursion issues might occur.
The following example demonstrates how to bind the checked state of a Kendo UI TreeView to a custom model field in AngularJS applications.
<link rel="stylesheet" href="https://demos.telerik.com/kendo-ui/content/shared/styles/examples-offline.css">
<script src="https://demos.telerik.com/kendo-ui/content/shared/js/console.js"></script>
<div id="example" ng-app="KendoDemos">
<div class="demo-section k-content" ng-controller="MyCtrl">
<div class="box-col">
<h4>TreeView bind to a custom isChecked property</h4>
<div kendo-tree-view="tree"
k-data-source="treeData"
k-options="options"
k-on-change="selecteditem=dataItem">
</div>
</div>
</div>
<div class="box">
<h4>Console log</h4>
<div class="console"></div>
</div>
</div>
<script>
angular.module("KendoDemos", ["kendo.directives"])
.controller("MyCtrl", function ($scope) {
$scope.options = {
loadOnDemand: false,
checkboxes: {
checkChildren: true,
template: "<input id='checkbox_#:item.uid#' ng-model='dataItem.isChecked' type='checkbox' class='k-checkbox'/>"
},
check: function(e) {
var currentItem = e.sender.dataItem(e.node),
modelItem = findModelItem($scope.treeData, currentItem.id);
updateChecked($scope.treeData, e.sender.dataSource.data());
$(".console").append("<p>Check event triggered by: " + currentItem.label + "</p>");
$(".console").append("<p>Data Source isChecked custom property: " + currentItem.isChecked + "</p>");
$(".console").append("<p>Model isChecked custom property: " + modelItem.isChecked + "</p>");
},
template: "#: item.label #"
};
$scope.treeData = [
{
"label": "Alex's family tree",
"isChecked":true,
"id": null,
"items": [
{
"id": 1,
"label": "Reef",
"isChecked": true
},
{
"id": 2,
"label": "Coraline",
"isChecked": true
}
]
}
];
// this is only to display the relevant model checked state for the demo
function findModelItem(model, id) {
for (var i = 0; i < model.length; i++) {
var currentItem = model[i];
if(currentItem.id === id){
return currentItem;
}
if (currentItem.items) {
var found = findModelItem(currentItem.items, id);
if (found) {
return found;
}
}
}
}
// copy checked state from datasource to model
function updateChecked(model, dataSource) {
for (var i = 0; i < model.length; i++) {
var dataItem = model[i];
var node = dataSource[i];
if (node.checked != undefined) {
dataItem.isChecked = node.checked;
}
if (dataItem.items) {
updateChecked(dataItem.items, node.children.data());
}
}
}
})
</script>
<style>
body {
font: 12px 1.5 Arial,sans-serif;
}
.demo-section:not(.wide), #example .box:not(.wide) {
max-width: 700px !important;
}
.k-treeview .k-in {
padding: 5px;
}
</style>