Wrong binding in grid when using same property name

6 posts, 1 answers
  1. Pascal
    Pascal avatar
    14 posts
    Member since:
    Mar 2016

    Posted 15 Dec 2016 Link to this post

    Hello Telerik team,

    thank you for your work and support so far.

    We have a blocking problem when binding our data to a grid.

    The problem is that while the data is initially correctly bound when calling kendo.bind ; the wrong model field is then used when adding new data to the grid data source. This occurs because the grid data source properties name are the same of the model root property names.

     

    I have reproduced the problem in the following dojo : http://dojo.telerik.com/OnuZA

    You can see in the previous example that the data is correctly bound initially.
    When you enter a new record in the grid it affects the root of the view model and not the array where the data source is bound !

    Is it the desired behavior ? If not have you a way to fix this problem until it get fixed in a next release ?

     

    Thank you !

  2. Stefan
    Admin
    Stefan avatar
    912 posts

    Posted 16 Dec 2016 Link to this post

    Hello Pascal,

    The described behaviour is expected because when a DataSource is not used and a new item is added, there is only an empty field in the object. Then the MVVM implementation is bubbling up and checking the parent elements to find the fields, and in this scenario is finding the firstName and the lastName from the ViewModel and it is replacing the initial fields with them.

    In this scenario, I can suggest using a DataSource and its schema.model property to set the fields of the DataSource. This will prevent the undesired effect because it will correctly match the fields from the DataSource model:

    http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-schema.model

    I modified the provided example to work as expected:

    http://dojo.telerik.com/uxEPe

    I hope this will help to achieve the desired result.

    Regards,
    Stefan
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Pascal
    Pascal avatar
    14 posts
    Member since:
    Mar 2016

    Posted 16 Dec 2016 in reply to Stefan Link to this post

    Hello Stefan,

    Thanks for your answer. I tried to implement your proposed example but in our scenario it does not fit well.

    When we bind our model with kendo.bind() our model is the json sent by the web server. And our various grids data are expressed as json arrays, and the wrapped in ObservableArrays that we track for a changes detection mechanism.

    So our grids data-bind attributes only references "source:MySource" where MySource is an ObservableArrays.
    I have not found an easy way to circumvent the problem by assigning a dataSource schema model to the dataSource of the grid at some moment.

    I tried to do it in one of our custom binder that do a grid.setOptions({columns: columnsDefinition}) to handle correct column definition. But the data source binding seems to occur after.

    I cannot modify our json model to transform my array in a dataSource because it break our changes detection mechanism based on ObservableArray.

    Is there an easy way to do this ? I'm thinking of a custom binder instead of "source" but this is becoming a mess.
    I think the grid should expose an option to be able to define it's own correct dataSource model when mvvm binding to prevent modifying data outside of the grid's data boundary.

    I find this grid default behavior quite strange for the grid when you bind data to it because you are not sure your modification will affect grids data only depending on other model properties renaming. This could become easily a mess after some refactoring.

    So I will try a custom "source" binding unless you have an easier solution.

  4. Stefan
    Admin
    Stefan avatar
    912 posts

    Posted 20 Dec 2016 Link to this post

    Hello Pascal,

    The provided suggestion is the only one which is supported out of the box when the fields of the Grid and the properties of the model have the same names.

    Other options are to have specific naming conventions for the properties and the fields to ensure that the names cannot be the same or to use the suggested custom binding.

    Apologies for the inconvenience this may cause you.

    Please let me know if you need additional information on this matter.

    Regards,
    Stefan
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Pascal
    Pascal avatar
    14 posts
    Member since:
    Mar 2016

    Posted 02 Mar Link to this post

    Here we went with a custom grid source binder, by ensuring the presence of a schema model in the data source :
    Here is the typescript implementation in the case that may help someone :

    /**
     * This allow setting a source with a model to a grid as it is not supported by kendo
     */
    let binder = kendo.data.Binder.extend({
        init: function(element, bindings, options) {
            kendo.data.Binder.fn.init.call(this, element, bindings, options);
     
            const data = bindings.gridSource.get();
            const dataSourceSchema = (element.dataSource.schema || {}) as kendo.data.DataSourceSchema;
     
            const dataSourceModel = dataSourceSchema.model || (dataSourceSchema.model = {});
            
            if (dataSourceModel.fields == undefined) {
                dataSourceModel.fields = {};
            }
     
            const gridColumns = bindings.gridColumns.get();
            const gridColumnsLength = gridColumns.length;
            for (let index = 0; index < gridColumnsLength; ++index) {
                const gridColumn = gridColumns[index];
                const field = gridColumn.field;
                if (field == undefined) {
                    continue;
                }
     
                dataSourceModel.fields[field] = gridColumn.defaultValue == undefined
                    ? field
                    : {
                        defaultValue: gridColumn.defaultValue
                    };
            }
     
            const dataSource = new kendo.data.DataSource({
                data: data,
                schema: dataSourceSchema
            });
             
            element.setDataSource(dataSource);
        },
     
        refresh: () => {}
    });
    kendo.data["binders"].gridSource = binder;
    kendo.data["binders"].widget.gridSource = binder;
  6. Answer
    Stefan
    Admin
    Stefan avatar
    912 posts

    Posted 02 Mar Link to this post

    Hello Pascal,

    Thank you for sharing the implementation with the Kendo UI community.

    We do appreciate the sharing of custom implementations which can be helpful for others. 

    Regards,
    Stefan
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top