This is a migrated thread and some comments may be shown as answers.

DataSource (stand-alone) and Knockout: sync() not working

1 Answer 154 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Eric
Top achievements
Rank 1
Eric asked on 17 Jul 2013, 06:36 AM
Hello Support,

We're using DataSource in a stand-alone manner, simply using it as a gateway to and from Web API endpoints.  It's been great for reads.  But now we've come to editing and creating, and we're not having any luck.

Consider the projectsDataService below.  The projectsDataService provides a gateway to an enumerable of Project, which has all of the familiar fields you would expect of a Project class:
01.define('projectsDataService', ['underscore'],
02.    function(_) {
03.        var projectsDataSource = new kendo.data.DataSource({
04.                transport: {
05.                    read: {
06.                        url: "api/projects",
07.                        dataType: "json"
08.                    },
09.                    update: {
10.                        url: "api/projects",
11.                        dataType: "json",
12.                        type: 'PUT'
13.                    }
14.                },
15.                page: 1,
16.                pageSize: 20,
17.                schema: {
18.                    model: {
19.                        location: function() {
20.                            return this.projectAddress.city + ", " + this.projectAddress.state.abbr;
21.                        },
22.                        encodedProjectAddress: function () {
23.                            //implement Strategy pattern for encoding
24.                            var fullAddress = this.projectAddress.streetAddress + ",+" +
25.                                this.projectAddress.city + ",+" +
26.                                this.projectAddress.state.abbr;
27. 
28.                            return fullAddress.replace(/ /g, "+");
29.                        },
30.                        multilineProjectAddress: function() {
31.                            var address = [this.projectAddress.streetAddress,
32.                                '<br/>',
33.                                this.location() + '  ' + this.projectAddress.postalCode].join('\n');
34. 
35.                            return address;
36.                        },
37.                        created: function() {
38.                            return moment(new Date(this.createdAt)).fromNow();
39.                        }
40.                    }
41.                }
42.            }),
43. 
44.            getProjects = function (projectsObservableArray) {
45.                projectsDataSource.fetch(function() {
46.                    var dataView = projectsDataSource.view();
47.                    var projects = [];
48.                    _.each(dataView, function (item) {
49.                        
50.                        projects.push(ko.observable(item));
51.                    });
52.                    projectsObservableArray(projects);
53.                });
54.            },
55.             
56.            saveProjects = function() {
57.                projectsDataSource.sync();
58.            };
59. 
60.        return {
61.            getProjects: getProjects,
62.            saveProjects: saveProjects
63.        };
64.    }
65.);
All of the computed-s on the model are available to Knockout, as expected.  Nothing wrong there.  But I have a couple of questions:
  1.   ProjectAddress is a nested complex type, so that I have projectAddress.streetAddress, projectAddress.city, projectAddress.state, etc.  Changes in these properties are, in fact, manifested in the UI (courtesy of Knockout), but changing them doesn't trigger a call to the transport.  In other words, the changes never make it to the server.  I get the sense that DataSource is expecting flattened data.  If so, how do I go about doing that the "DataSource" way?
  2.  Is the fields property necessary on the model, and what is the difference between binding to a field on the model, and binding to a field in the fields property?
  3.   Consider the getProjects() function.  I'm stuffing a knockout array with an array of oversables--the projects.  Should I be making each of Project's properties observable as well in order for the DataSource to pick up on the change?  The problem is that I'm seeing changes in the client, even across multiple screens, ut no call to the server.
  4. Is the "id" property, or field, necessary on the model?
  5. Is it necessary to mapevery property ("field") on the model, or just those that are interesting, as in the code above?
Thank you.

Eric

1 Answer, 1 is accepted

Sort by
0
Alexander Valchev
Telerik team
answered on 19 Jul 2013, 08:13 AM
Hello Eric,

Thank you for contacting us. First of all I would like to note that I am not an expert in Knockout. Form Kendo UI point of view:

Changes in these properties are, in fact, manifested in the UI (courtesy of Knockout), but changing them doesn't trigger a call to the transport.

How do you change the model properties? The values should be changed via set method - in this way the observable object will notify the DataSource that it was changed (Kendo MVVM). Simply changing the value with "=" operator will not work.

I get the sense that DataSource is expecting flattened data.  If so, how do I go about doing that the "DataSource" way?

Your understanding is correct - DataSource works with flattened data. Generally speaking you should be able to edit items and submit the changes. I assume that the problem might be related to the missing ID/not using the set method.

Is the fields property necessary on the model, and what is the difference between binding to a field on the model, and binding to a field in the fields property?

The fields and id configuration are necessary for the editing functionality. Omitting them is not recommended. Fields properties are used to describe the data - e.g. the type of the field, default values etc. For more information please refer to this help topic:
I'm stuffing a knockout array with an array of oversables--the projects.  Should I be making each of Project's properties observable as well in order for the DataSource to pick up on the change?  The problem is that I'm seeing changes in the client, even across multiple screens, ut no call to the server.

If you would like to edit the DataSource's data, please use the API methods:
Add, insert, remove, etc. If you would like to edit the value of a specific field, use at/get/getByUid to obtain reference to the records and set method to change the value.

Is the "id" property, or field, necessary on the model?

Yes it is. Each record must have a unique ID. Records with empty ID are considered as new and submitted via create transport.

Is it necessary to mapevery property ("field") on the model, or just those that are interesting, as in the code above?

It is not necessary, however it is recommended in order to avoid potential problems.

I hope this information will help. To summarize, I believe that the changes are not submitted, because modifications in the data are not made via Kendo DataSource/Model methods.
 
Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Data Source
Asked by
Eric
Top achievements
Rank 1
Answers by
Alexander Valchev
Telerik team
Share this question
or