Question

I am attempting to develop a Mobile app using Kendo Mobile's MVVM and JayData Data Access Library. I have run into an issue that I have worked on for about a week now with no luck. I am looking for a simple example consisting of Kendo two way binding using a model that is created by JayData's (asKendoDataSource) having an inverseProperty navigation property. I am not sure that JayData kendo.js Module supports models containing inverseProperty and in the process of testing, even after getting the data to save with the relationship, retrieval of the same record does not pull the relational data back into the viewmodel.

Can anyone provided a simple example of Saving and Retrieving such a model using the webSql provider?

Any help is greatly appreciated.

JayData Models (simplified):

//Expense Category Model
$data.Entity.extend('data.types.ExpenseCategory', {
    Id: { type: 'Edm.Guid', key: true },
    CategoryName: { type: 'string', required: true, minLength: 3, maxLength: 26 },
    Expenses: { type: Array, elementType: "data.types.Expense", inverseProperty: "Category" }
});

//Expense Model
$data.Entity.extend('data.types.Expense', {
    Id: { type: 'Edm.Guid', key: true },
    ExpenseDescription: { type: 'string', required: true },
    Category: { type: "data.types.ExpenseCategory", inverseProperty: "Expenses" }
});

// Entity Context 
$data.EntityContext.extend('data.types.DbContext',
{
    ExpenseCategories: { type: $data.EntitySet, elementType: data.types.ExpenseCategory },
    Expenses: { type: $data.EntitySet, elementType: data.types.Expense },

});

// Database Context 
data.context = new data.types.DbContext({ name: 'sqLite', databaseName: 'cDb' });

Kendo Viewmodel (simplified):

views.expenseCategoryPicker = kendo.observable({
    app: null,
    categories: db.context.ExpenseCategories.asKendoDataSource(),
    expense: null,
    itemClick: function(sender) {

        var expense = views.expenseCategoryPicker.expense;
        expense.set('Category', sender.data);

        ...add/update logic

        expense.sync();

    },
    loadExpense: function(dataItem) {

        views.expenseCategoryPicker.set('expense', undefined);
        views.expenseCategoryPicker.set('expense', dataItem);        
    },
});

EDIT

I figured out why the data won't save and a work around. There is a bug in JayData's kendo.js module when using the Kendo MMVM binding and inverseProperty relationships. They(JayData) simply don't support their own Attach method when an object relationship is being set through their Kendo module. Therefor when you call Kendo's SET on the model passing in the related Object the Entity state on the Object being passed in is set to 20 (New) and JayData tries to create a new record and in my case failing due to primary key conflict. The Attach method sets the Entity state to unmodified.

I know there is probably a more elegant way to fix this in JayData's code, but for me simply adding the following line right before I use the Kendo set method to set the object relationship allows the record to be saved without error.

itemClick: function(sender) {

    var expense = views.expenseCategoryPicker.expense;

    //manually set the state so SQL won't try to create a new record
    sender.data.innerInstance()._entityState = 10;  

    expense.set('Category', sender.data);
    ...

Subsequent reads require the Include('model') method to load the relational data as mentioned by Robesz (THANK YOU)

It would be nice to see JayData fix the data save issue in their Kendo module.

Was it helpful?

Solution

JayData doesn't load the related entities by default, you have to use the include() operator:

data.context.Expenses.include('Category').toArray(...)

The parameter of the include should be the name of the navigation property.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top