Give kendo datasource an angular scope variable
Asked Answered
P

4

6

I'm currently trying to fill a kendo grid with remote data. Kendo has its own function to fetch the data, but I want to use the angular factory which I created.

So I have a factory, which has a function "getSkills". This function obtains all the skill objects from my api.

angular.module('MyApp').factory('Factory', function ($resource) {
    return $resource('/api/v1/skills/', {  },
        {
            getSkills: { method: 'GET', isArray: true }
        });
});    

In my SkillController in angular, I put these fetched skills in a scope variable.

$scope.skills = SkillFactory.getSkills();

I initialize the Kendo grid here:

$scope.gridOptions = {
                dataSource: {
                    data: $scope.skills,
                    schema: {
                        model: {
                            fields: {
                                ID: { type: "number" },
                                Name: { type: "string" },
                                CreatedBy: { type: "number" },
                                CreatedDate: { type: "string" },
                                EditedBy: { type: "number" },
                                EditedDate: { type: "string" },
                                InUse: { type: "boolean" }
                            }
                        }
                    },
                    pageSize: 20
                },
                scrollable: true,
                sortable: true,
                filterable: true,
                pageable: {
                    input: true,
                    numeric: false
                },
                selectable: true,
                columns: [
                    { field: "Name", title: "skillname", width: "130px" }
                ]
            };

Most of the times, the ajax callback is slower than the initialization of the kendo grid. Then it will show an empty table, because the data of the table isn't bound to the angular $scope.skills variable.

I have searched everywhere, but I can't figure out how I can use a custom function for the data attribute in the initialization, or how to bind the scope variable to the table.

Any help would be appreciated!

Prefatory answered 10/10, 2013 at 7:43 Comment(0)
B
7

I found a little simpler solution: In my case $scope.regs defines the data which is updated from server REST service using Angular $resource exposed with "AppService". This service is defined as:

    var registrationServices = angular.module('registrationServices', ['ngResource']);

    registrationServices.factory('AppService', ['$resource',
        function($resource) {
            return $resource('rest/registrations');
    }]);
  1. I set k-auto-bind = "false" to grid definition in HTML:

    <div id="form-item">
     <label for="appId" class="info">AppId:</label>
     <input id="appId" ng-model="searchAppId"> 
     <button id="search" class="k-button" ng-click="doSearch()" >Search</button>
    </div>  
    
    <div kendo-grid  k-data-source="registrations" k-selectable="'row'"
      k-pageable='{ "refresh": true, "pageSizes": true }'
      k-columns="registrationsColumns"
      k-sortable="true" k-groupable="true" k-filterable="true"
      k-on-change="selectedItem = data"
      k-auto-bind="false" >
    </div>
    
  2. Instead of binding Kendo grid datasource using "data" property, I used "transport" with "read" defined as function, something like that:

      $scope.regs;
    
     $scope.registrations = new kendo.data.DataSource({
        transport: {
            read: function(options) {
                options.success($scope.regs);
            }
        },
        schema: {
            model: {
                fields: {
                    registrationId: {type: "number"},
                    clientFullName: {type: "string"},
                    registrationDate2: {type: "number"},
                    registrationDate: {type: "date"}
                }
            }
        },
        pageSize: 5,
        serverPaging: true,
        serverFiltering: true,
        serverSorting: true
    });
    
    
    $scope.registrationsColumns = [{"field": "registrationId", "title": "Id"},
        {"field": "clientFullName", "title": "Name"},
        {"field": "registrationDate",
            "title": "Registration Date",
            format: "{0:dd/MM/yyyy}",
            filterable: {ui: dateFilter, extra: "false"}
        }
    ];
        ....
    
  3. Then, when I want to refresh data in the grid, I use callback using Angular $resource. :

    $scope.doSearch = function() {
        $scope.regs = AppService.query({"regId": $scope.searchAppId}, function(result) {
            $scope.registrations.read();
        });
    };
    

It works. Additional advantage of this solution is, you don't have to move grid creation to Java Script code, it can stay in HTML.

Bibulous answered 17/12, 2013 at 22:43 Comment(1)
I know this post is old but I notice you have serverPaging set as True. How do you pass Kendo's grid paging data along with your request or does it get passed in the request body? I'm trying to do this myself but keep paging workingGarbanzo
M
6

Something like this will get you on the correct path. You can simple call your factory from with in the transport read method. You just can't mix and match them either all of you read,create, and destroy methods have to use a factory or they all have to explicitly call the end point ie url: '/api/myservice/' Instead of using $http just consume your factory like you would in any other place with in your app:

$scope.Source = new kendo.data.DataSource({

    transport: {

        read: function (options) {

            return $http.post('/api/getReportData/', {sDate: '', eDate: ''})
                .success(function (data) {

                    options.success(data);
                    Toaster.Info("Refreshed");

                })
                .error(function () {
                    return;
                });

            console.log("mmm");
        }

    }

});
Mecham answered 5/8, 2014 at 15:18 Comment(1)
Yeah this looks very similar to how I ended up doing it! thanks!Prefatory
P
0

I fixed this doing the following:

I gave my resource function a callback like this:

SkillFactory.getSkills({},
    function success(data) {
        createGrid(data);
    });

In the function createGrid(data); I initialize the data like this:

 function createGrid(gridData) {
$("#skillGrid").kendoGrid({
   dataSource: {
   data: gridData,
   schema: {
      model: {
        fields: {
              ID: { type: "number" },
              Name: { type: "string" },
              CreatedBy: { type: "number" },
              CreatedDate: { type: "string" },
              EditedBy: { type: "number" },
              EditedDate: { type: "string" },
              InUse: { type: "boolean" }
                }
             }
          },
       pageSize: 20
       },

So in the data attribute of the initialization I set the data when it is successfully fetched. I hope this helps!

Prefatory answered 10/10, 2013 at 9:0 Comment(0)
M
-2

Have you looked at $q promises in Angular ? See $q promises in Angular

Monomolecular answered 16/7, 2014 at 20:42 Comment(3)
This has nothing to do with the question.Mecham
@pehaada, using a promise would ensure that the data is fetched prior to calling the grid-rendering routine.Monomolecular
While your statement is correct it is not the answer that he is looking for. Your answer is like me saying a REST based web service will help you return data.Mecham

© 2022 - 2024 — McMap. All rights reserved.