jaystack / jaydata

Notice: this library isn't maintained anymore
http://jaydata.org
GNU General Public License v2.0
354 stars 95 forks source link

Does asKendoDatasource() work in the context of OData4? #252

Open odnodn opened 8 years ago

odnodn commented 8 years ago

After struggling a lot due to a lack of proper odata 4 / angularJS examples I finally managed to get jayData to work with odata4/angularjs. But as soon as I try to bind an entity to a kendo widget via context.Entity.asKendoDatasource(), i.e. the grid widget, it seems that an datasource object gets created, but not reflecting the underlying schema (I have not included the model generated by jaysvcutil from an odata 4 endpoint as I am using the context.init("odata4endpoint") method). Does asKendoDatasource() only works with odata 1-3 schemas? Do you happen to have an example working with jaydata / odata 4 / angularJS / kendoUI widget?

Thanks a lot.

this is what I get logging the resulting object (context.Entity.asKendoDatasource()) to the console, schema, model and transport declarations are missing:

{"options":{"data":null,"schema":{"data":"data","total":"total"},"offlineStorage":null,"serverSorting":true,"serverPaging":true,"serverFiltering":true,"serverGrouping":false,"serverAggregates":false,"batch":false,"pageSize":25,"transport":{"items":[]}},"_map":{},"_prefetch":{},"_data":[],"_pristineData":[],"_ranges":[],"_view":[],"_pristineTotal":0,"_destroyed":[],"_pageSize":25,"_page":1,"_group":[],"_shouldDetachObservableParents":true,"_events":{},"transport":{"items":[],"options":{}},"reader":{},"_online":true}

{
   "options":{
      "data":null,
      "schema":{
         "data":"data",
         "total":"total"
      },
      "offlineStorage":null,
      "serverSorting":true,
      "serverPaging":true,
      "serverFiltering":true,
      "serverGrouping":false,
      "serverAggregates":false,
      "batch":false,
      "pageSize":25,
      "transport":{
         "items":[

         ]
      }
   },
   "_map":{

   },
   "_prefetch":{

   },
   "_data":[

   ],
   "_pristineData":[

   ],
   "_ranges":[

   ],
   "_view":[

   ],
   "_pristineTotal":0,
   "_destroyed":[

   ],
   "_pageSize":25,
   "_page":1,
   "_group":[

   ],
   "_shouldDetachObservableParents":true,
   "_events":{

   },
   "transport":{
      "items":[

      ],
      "options":{

      }
   },
   "reader":{

   },
   "_online":true
}
ysmoradi commented 8 years ago

I've developed an application based on jaydata - kendo integration and Web API OData 4. I cloned and built latest jaydata code for my app. I had to modify some lines of jaydata kendo module codes. But, I didn't faced any problem about schema.

odnodn commented 8 years ago

Hi, thanks for your reply. Which example are you referring? Are you using the schema discovery method (context.init().then() ...) or a prebuild schema generated by jaysvcutil? Do you happen to have a small working example which could help me to track down what I am probably doing wrong? Thanks a lot in advance.

ysmoradi commented 8 years ago

I'm generating something like this: https://github.com/jaystack/odata4-webapi-endpoint/blob/development/WebApi_2_2_OData_4/client/JayDataContext.js with Roslyn, after successful build, from my C# codes. I don't appreciate jay svc util, because it needs server to be running. I try to create a small project for you. For now, are you waiting for context.ready? And what's a result of as a kendo columns? Which version of kendo are you using?

odnodn commented 8 years ago

I really appreciate your help, thank you very much. I would be happy to see a small running project. I am using the $data.init function which automatically discovers the model like $data.init('url').then(function(context){$scope.context = context; $scope.Entity = context.Entity.toArray()}). I can bind to an agular template and can see the data I queried. I am not sure whether asKendoDataSource() needs a pre-build dataContext model from jaysvcutil or any other tool or it might use the model discovered by $data.init('url'). When logging the result of asKendoDataSource() I get what I posted in my first post, Imust do something wrong.

This is what I have so far:

var app = angular.module('app', ['jaydata', 'kendo.directives']);

app.factory('contextFactory',
    [
    '$data',
    '$q',
    function ($data, $q) {
        return {
            getContext: function () {
                var defer = $q.defer();
                $data.initService('http://pneumologie/test/JaydataTest/')
                .then(function onFullfilled(context) {
                    defer.resolve(context);
                },
                function onRejected(error) { defer.reject(error) });
                return defer.promise;
            }
        }
    }])

app.controller('AerzteController', ['$scope', '$data', 'contextFactory', function ($scope, $data, contextFactory) {
    $scope.Aerzte = [];
    $scope.selectedArzt = null;
    $scope.kendoDatasource = null;
    $scope.context = null;

    contextFactory.getContext().then(function (context) { console.log(JSON.stringify(context.Aerzte.asKendoDataSource())) });

    contextFactory.getContext()
        .then(function (context) {
            $scope.context = context;
            context.Aerzte.toArray()
                .then(function (result) {
                    // console.log(result)                    
                    $scope.$apply(function () {
                        $scope.Aerzte = result;
                    });

                    $scope.kendoDatasource = context.Aerzte.asKendoDataSource();
                    console.log($scope.kendoDatasource);
                    console.log(JSON.stringify($scope.kendoDatasource));
                    $('#grid').kendoGrid({ options: $scope.options });
                    //$('#grid').kendoGrid({ dataSource: $scope.kendoDatasource, options: $scope.options });
                })
        }, function (error) { console.log(error) });

    $scope.save = function () {
        if ($scope.selectedArzt.ArztId) {
            // save existing
            $scope.context.Aerzte.attach($scope.selectedArzt, true);
            $scope.selectedArzt.entityState = $data.EntityState.Modified;
        }
        else {
            // save new
            $scope.context.Aerzte.add($scope.selectedArzt, true);
        }
        $scope.saveChanges() // no promise ! .then(function () { $scope.$apply(); }).catch(function (error) { console.log(error); });        
    };

    $scope.saveChanges = function () {
        //console.log('before saveChanges');
        var promise = $scope.context.saveChanges(
            );
        //console.log('after saveChanges');

        promise.then(function () {
            console.log('successfully saved');
            $scope.selectedArzt = null;
        })
    }

    $scope.remove = function () {
        var aerzte = $scope.Aerzte;
        aerzte.remove($scope.selectedArzt)
        .then(function () {
            $scope.$apply(function () {
                aerzte.splice(aerzte.indexOf($scope.selectedArzt, 1));
            });
        })
        .fail(function () {
            alert('Fehler beim Speichern');
        });

        $scope.saveChanges();
    };

    $scope.newArzt = function () {
        var ctx = $scope.context;
        $scope.selectedArzt = new ctx.Aerzte.elementType({Name: "neuer Arzt"})
    };

    $scope.addNew = function (item) {
        $scope.context.Aerzte.save(item).then(function () {
            $scope.$apply(function () {
                $scope.Aerzte.push(item);
            })
        })
    };

    $scope.$watch('search', function (search) {
        if ($scope.context == null) {
            return;
        }
        var context = $scope.context;

        var promise = (search ? context.Aerzte.filter('it.Name.startsWith(p)', { p: search }).toArray() : context.Aerzte.toArray());
        promise.then(function (result) {
            $scope.$apply(function () {
                $scope.Aerzte = result;
            });
        });
    });
}])

This is my index file header:

    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.504/styles/kendo.common.min.css" />
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.504/styles/kendo.rtl.min.css" />
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.504/styles/kendo.silver.min.css" />
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.2.504/styles/kendo.mobile.all.min.css" />

    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/odatajs-4.0.0/odatajs-4.0.0.min.js"></script>

    <script type="text/javascript" src="Scripts/moment/moment.js"></script>
    <script src="Scripts/angular.min.js"></script>
    <script src="http://kendo.cdn.telerik.com/2016.2.504/js/kendo.all.min.js"></script>

    <script src="Scripts/jaydata/jaydata.js"></script>
    <script src="Scripts/jaydata/jaydatamodules/angular.js"></script>
    <script src="Scripts/jaydata/jaydatamodules/kendo.min.js"></script>
    <script src="Scripts//jaydata/jaydatamodules/deferred.min.js"></script>
    <script src="Scripts/jaydata/jaydataproviders/oDataProvider.min.js"></script>

    <script src="app/app.js"></script>

I am using the latest kendo version.

How do you generate the model with the help of roslyn?

odnodn commented 8 years ago

Hello Yasser, did you manage to have some time to create a small example project with odata4/kendoUI? I would really appreciate this kind of help. Thank you in advance for your kind efforts.

ysmoradi commented 8 years ago

I'm so sorry, I was really busy. Could you please replace the jaydata kendo.js module of yours with this one? kendo.zip

jamiefraser commented 5 years ago

@ysmoradi. Thank you! Have been struggling with an oData issue for the past couple of days. This seems to have fixed me up!

ysmoradi commented 5 years ago

@jamiefraser Use our new release We've fixed lots of issues in 57 commits!