-----------------
If you are new to AngularJS, then I recommend you to read my first article that I have written for beginners.
AngularJS Tutorial for Beginners – My First AngularJS App “Hello World”
-----------------
The UI-Grid has many useful features, many of which I’ll discuss in my later posts. One good thing about the UI-Grid is that it performs well with large data set, or in other words, you can work with thousands of rows of data, without compromising with performance.
You can apply paging, sort columns in Ascending and Descending order, filter columns and more.
This post covers one very important thing that is binding the UI-Grid to a dynamic data source using Asp.Net Web API MVC 4. The data source I am using here is an SQL Server table.
Create this table and add few rows to it.
CREATE TABLE [dbo].[Books]( [BookID] [int] IDENTITY(1,1) NOT NULL, [BookName] [varchar](50) NULL, [Category] [varchar](50) NULL, [Price] [numeric](18, 2) NULL PRIMARY KEY CLUSTERED ( [BookID] ASC ) ) ON [PRIMARY]
My Web API has a model and a controller, where I’ll have a function to take and process the requests. Its MVC 4 in Asp.Net. Therefore, you must have Visual Studio 2010 or more installed on your computer.
using System; namespace BooksApp.Models { public class Books { public int BookID { get; set; } public string BookName { get; set; } public string Category { get; set; } public decimal Price { get; set; } public string Operation { get; set; } } }
Imports System.Web Namespace BooksApp.Models Public Class Books Public Property BookID() As Integer Get Return m_BookID End Get Set(value As Integer) m_BookID = value End Set End Property Private m_BookID As Integer Public Property BookName() As String Get Return m_BookName End Get Set(value As String) m_BookName = value End Set End Property Private m_BookName As String Public Property Category() As String Get Return m_Category End Get Set(value As String) m_Category = value End Set End Property Private m_Category As String Public Property Price() As Decimal Get Return m_Price End Get Set(value As Decimal) m_Price = value End Set End Property Private m_Price As Decimal Public Property Operation() As String Get Return m_Ops End Get Set(value As String) m_Ops = value End Set End Property Private m_Ops As String End Class End Namespace
Now, lets create our controller.
using System; using System.Collections.Generic; using System.Net; using System.Net.http; using System.Web.http; using BooksApp.Models; using System.Data.SqlClient; namespace BooksApp.Controllers { public class BooksController : ApiController { const string sConnString = "Data Source=DEMO;Persist Security Info=False;" + "Initial Catalog=DNA_Classified;User Id=sa;Password=;Connect Timeout=30;"; // LIST OBJECT WILL HOLD AND RETURN A LIST OF BOOKS. List<Books> MyBooks = new List<Books>(); [HttpPost()] public IEnumerable<Books> Perform_CRUD(Books list) { using (SqlConnection con = new SqlConnection(sConnString)) { SqlCommand objComm = new SqlCommand("SELECT *FROM dbo.Books ORDER BY BookID DESC", con); con.Open(); SqlDataReader reader = objComm.ExecuteReader(); // POPULATE THE LIST WITH DATA. while (reader.Read()) { MyBooks.Add(new Books { BookID = Convert.ToInt32(reader["BookID"]), BookName = reader["BookName"].ToString(), Category = reader["Category"].ToString(), Price = Convert.ToDecimal(reader["Price"]) }); } con.Close(); } return MyBooks; } } }
The controller has a public method called Perform_Crud. This method is called from a Client app using http POST and returns a List of Data to the requested app.
Option Explicit On Imports System.Net.http Imports System.Web.http Imports System.Data.SqlClient Imports BooksApp.BooksApp.Models Namespace BooksApp Public Class BooksController Inherits ApiController Const sConnString As String = "Data Source=DEMO;Persist Security Info=False;" & _ "Initial Catalog=DNA_Classified;User Id=sa;Password=;Connect Timeout=30;" ' LIST OBJECT WILL HOLD AND RETURN A LIST OF BOOKS. Dim MyBooks As New List(Of Books)() <HttpPost()> _ Public Function Perform_CRUD(list As Books) As IEnumerable(Of Books) Using con As SqlConnection = New SqlConnection(sConnString) Dim objComm As New SqlCommand("SELECT *FROM dbo.Books ORDER BY BookID DESC", con) con.Open() Dim reader As SqlDataReader = objComm.ExecuteReader() ' POPULATE THE LIST WITH DATA. While reader.Read() MyBooks.Add(New Books() With { _ .BookID = CInt(reader("BookID")), _ .BookName = reader("BookName").ToString(), _ .Category = reader("Category").ToString(), _ .Price = CDbl(reader("Price")) _ }) End While con.Close() End Using Return MyBooks End Function End Class End Namespace
We are now done with our backend. Now lets create our frontend, which will have the AngularJS UI-Grid.
First, we’ll add the AngularJS libraries (two .js files and a .css file), inside the <head> section. In the <body> section or the view, I have a <div> element to which I have defined the ui-grid directive. We all need to specified the data (source), typically a JSON object. The data property is referencing the $scope.gridData property in the controller.
<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.6.3/ui-grid.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.6.3/ui-grid.min.css" type="text/css"> <style> p, div { font:15px Verdana; } .uiGrd { width: 550px; height: 300px; } </style> </head> <body> <div ng-app="myApp" ng-controller="myController"> <p>{{title}}</p> <div class="uiGrd" id="grd" ui-grid="gridData"></div> </div> </body>
<script> var myApp = angular.module('myApp', ['ui.grid']); myApp.controller('myController', function ($scope, $http) { $scope.title = "AngularJS UI-Grid Example"; Perform_CRUD('READ'); function Perform_CRUD(ops) { var request = { method: 'post', url: '/api/books/', data: { Operation: ops }, dataType: 'json', contentType: "application/json" }; $scope.arrBooks = new Array; // POST DATA WITH $http. $http(request) .success(function (data) { var i = 0; // JUST A COUNTER. // LOOP THROUGH EACH DATA. angular.forEach(data, function () { var b = { BookID: data[i].BookID, BookName: data[i].BookName, Category: data[i].Category, Price: data[i].Price }; $scope.arrBooks.push(b); // ADD DATA TO THE ARRAY. i += 1; }); }) .error(function () { }); $scope.gridData = { data: 'arrBooks' }; }; }); </script> </html>
First, you'll have to add the ui.grid module to your controller, as dependency.
var myApp = angular.module('myApp', ['ui.grid']);
I am using AngularJS $http service to post data to the Web API. I am using the POST method, since this example is originally designed to do CRUD operations using the UI-Grid. I’ll share the CRUD example later in this blog. Meanwhile, we’ll focus on the data binding part.
Once the API successfully processes the request, it will return a list of data (rows). We’ll loop through each row using AngularJS .forEach() method and push the data array to a property called arrBooks.
$scope.arrBooks.push(b);
The array or the $scope property arrBooks, is the data source for the UI-Grid.
$scope.gridData = { data: 'arrBooks' };