javascriptkendo-uikendo-mvvm

Kendo UI template variable scope


As per this fiddle...

http://jsfiddle.net/ztn4dvrL/2/

I'm creating a dropdown menu with a template. I'm trying to figure out the context of variables.

<td><select data-bind="source: roles, value: roleId" data-template="selectRoleTemplate"></select></td>

the source, roles is a field in the viewmodel.

the value, roleId is a field of person, which is a field of the viewmodel.

I was expecting that, to be able to address a variable in the viewmodel, we need something like base.roleId or super.roleId, but that doesn't seems to be the case. If we add a field called roles in the person object, the dropdown now binds to that variable even though nothing has changed in the view. This is very confusing. Is there any explanation for this hidden logic?

<script type="text/x-kendo-template" id="selectRoleTemplate">
    <option data-bind="value: id, text: name" />
</script>

In the template itself id and name are fields of the person object. Is there a way to address variables in the viewmodel from inside the personTemplate script tag? IE(company)


Solution

  • So from the two fiddles I have provided here is some added explanation:

    https://jsfiddle.net/ztn4dvrL/8

    So in this version all I am doing is declaring the data field/value items using kendo's data-attribute property declaration. so if you go through the api documentation and see something like

    $('combobox').kendoComboBox({ datasource: data, dataTextField: "Text", dataValueField:"Value"})
    

    each of these properties can be declared using the data-* properties so where you see casing e.g. dataTextField this is split out to data-text-field

    https://jsfiddle.net/ztn4dvrL/11/

    in this one I am doing what may seem a bit like magic and should be used only when no other solution can be applied.

    <td>
      <select data-bind="source: parent().parent().roles, value: roleId" data-text-field="name" data-value-field="id"></select>
    </td>
    

    So taking your model we have the following tree:

    Root (The One Element to control them all) >> People (Your Array) >> Person (Your Object)

    As we are in the template that is binding the Person Object we only know properties that are associated to this item or below. So if we want to provide access to a list of items at a different level ABOVE this item we either have interact with the view model outside of this code or traverse back the tree to get to the appropriate level.

    So if we want to access the roles array at the root level of the view model we first need to go to the parent of the person object but this only gets up to the Array of Person so we would have an undefined object. But if we go to the parent of the Array we get back to the root element and this then gives access to everything again.

    so:

    parent().parent().roles equates 
    

    to:

    {person}.{people array}.{root of viewmodel}.{roles array}
    

    Hopefully that helps explain what I have done. If there is anything missing or you need further expanding I will aim to add more explanation if I can.