All Components

Data Binding Basics

The main purpose of the Grid is to display your model data.

The appropriate type of data binding depends on your scenario and the features you need. You can bind the Grid to an Array or GridDataResult objects by setting the data property of the <kendo-grid> tag.

When you bind the Grid to data, note the following specifics:

  • When paging is disabled, bind the data directly as an Array object.
  • When paging or virtual scrolling is enabled, use the GridDataResult option. It enables you to set the total number of records in a different data length from the currently provided one.
  • When the data is received from an asynchronous source, pipe it through the async pipe.
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { CategoriesService } from './northwind.service';

import { State } from '@progress/kendo-data-query';

import {
    GridDataResult,
    DataStateChangeEvent
} from '@progress/kendo-angular-grid';

@Component({
    selector: 'my-app',
    template: `
       <kendo-grid
          [data]="view | async"
          [pageSize]="state.take"
          [skip]="state.skip"
          [sort]="state.sort"
          [sortable]="true"
          [pageable]="true"
          [scrollable]="'none'"
          (dataStateChange)="dataStateChange($event)"
        >
        <kendo-grid-column field="CategoryID" width="130"></kendo-grid-column>
        <kendo-grid-column field="CategoryName" width="200"></kendo-grid-column>
        <kendo-grid-column field="Description" [sortable]="false">
        </kendo-grid-column>
      </kendo-grid>
    `
})
export class AppComponent {
    public view: Observable<GridDataResult>;
    public state: State = {
        skip: 0,
        take: 5
    };

    constructor(private service: CategoriesService) {
        this.view = service;
        this.service.query(this.state);
    }

    public dataStateChange(state: DataStateChangeEvent): void {
        this.state = state;
        this.service.query(state);
    }
}



import { NgModule, enableProdMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule } from '@angular/common/http';

import { GridModule } from '@progress/kendo-angular-grid';

import { AppComponent }   from './app.component';
import { CategoriesService }   from './northwind.service';

enableProdMode();

@NgModule({
  imports:      [ BrowserModule, BrowserAnimationsModule, GridModule, HttpClientModule ],
  declarations: [ AppComponent ],
  providers:    [ CategoriesService ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './ng.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { GridDataResult } from '@progress/kendo-angular-grid';
import { toODataString } from '@progress/kendo-data-query';
import { Observable } from 'rxjs/Observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

import 'rxjs/add/operator/map';

export abstract class NorthwindService extends BehaviorSubject<GridDataResult> {
    private BASE_URL: string = 'https://odatasampleservices.azurewebsites.net/V4/Northwind/Northwind.svc/';

    constructor(
        private http: HttpClient,
        protected tableName: string
    ) {
        super(null);
    }

    public query(state: any): void {
        this.fetch(this.tableName, state)
            .subscribe(x => super.next(x));
    }

    protected fetch(tableName: string, state: any): Observable<GridDataResult> {
        const queryStr = `${toODataString(state)}&$count=true`;

        return this.http
            .get(`${this.BASE_URL}${tableName}?${queryStr}`)
            .map(response => (<GridDataResult>{
                data: response['value'],
                total: parseInt(response["@odata.count"], 10)
            }));
    }
}

@Injectable()
export class ProductsService extends NorthwindService {
    constructor(http: HttpClient) { super(http, "Products"); }

    public queryForCategory({ CategoryID }: { CategoryID: number }, state?: any): void {
        this.query(Object.assign({}, state, {
            filter: {
                filters: [{
                    field: "CategoryID", operator: "eq", value: CategoryID
                }],
                logic: "and"
            }
        }));
    }

    public queryForProductName(ProductName: string, state?: any): void {
        this.query(Object.assign({}, state, {
            filter: {
                filters: [{
                    field: "ProductName", operator: "contains", value: ProductName
                }],
                logic: "and"
            }
        }));
    }

}

@Injectable()
export class CategoriesService extends NorthwindService {
    constructor(http: HttpClient) { super(http, "Categories"); }

    queryAll(st?: any): Observable<GridDataResult> {
      const state = Object.assign({}, st);
      delete state.skip;
      delete state.take;

      return this.fetch(this.tableName, state);
    }
}
In this article