One of the strengths of modern websites is the use of client side technologies.In fact there are several libraries that can help us develop our work and are among the most popular jQuery.
Using these libraries we can more easily interact with the DOM (Document Object Model) than using the traditional JavaScript functions.
Furthermore, the ajax functions are much simpler to implement.
With jQuery, you can do many things, but not all ... or you can do them but some become very complex, such as dynamically create an html select tag.
$.each(someContinents, function (k, v) { $('select#selContinents').append($("").attr("value", k).text(v)); });
With a foreach jQuery function ($.each) we can iterate all elements (continents). Every iteration append an "option" html tag (with key and value) to html select tag. This is a very very simple example. Your data can come from several sources (webservice, array...).
Now introduce another way to populate a combo box, using less JavaScript code and a very powerful library: Knockout. It does not replace jQuery, but we can say that it can be an integration.
But we go one step at a time…
First, we create a sample table on a MS SQL database called “T_STATE” with two columns: id and description. Then populate it with some data like these:
Data table
This will be out data source. Now create a new ASP.NET application (or a MVC, one orthe other isindifferent).
Add a newADO.NET Entity Data Model and add the previous database table to its designer. That’s result:
Entity
I saved my Entity Container Name as “DbTestEntities”. Normally, I prefer to create a new libray project and create a new ADO.NET Entity Model inside it, so I can reuse it in other applications. Remember our saved name because it will serve for the next step: WCF data service.
Now we see how to interact with data stored on a database and client-side components. I decided to use the DataService because they are easy to implement, and through the OData protocol can be queried directly from the URL when calling the service. Of course you can also use other traditional REST webservices, but in this example we’ll use a WCF Data Service.
On Visual Studio 2010 project, add a new WCF Data Service. A new *.svc file will be created on our project. I saved it as “WcfDS.svc” Open this file and modify class code with parameters previous created in our entity model designer:
It’s important that DataService base class is of the type described on the entity container name. Remember, my previous name was “DbTestEntities”, so base class will be DataService.
First parameter will be the exact entity name (in my example it’s T_STATE) and right “AllRead”. These settings permit a read only permission in the table.
Press F5 to debug our project, navigate to our WCF Data Service Page (ex http://localhost:1340/WcfDS.svc/) and you can see something like this (it depend on used browser):
Then, as other library we need to reference these libraries in the html head tag. Suppose our path is in the script website directory, code will be following (in the example I use MVC 3 and Url helper):
We note that before we create a reference to the jQuery library, then Knockout. In this way we can ensure that any jQuery functions can be called and recognized with Knockuot. Now we can create JavaScript code to retrieve data and populate our drop down list (html select tag).
First we need to declare a class that represents our data. In this case, we need two fields: id and state name:
function StateDef(data) {
this.id = ko.observable(data.id);
this.State = ko.observable(data.State);
}
Data parameter represent single data read from webservice. Now create a new ViewModel JavaScript function and bind it into Knockout library:
function StatesViewModel() {
}
ko.applyBindings(new StatesViewModel());
Here StatesViewModel code:
function StatesViewModel() {
var self = this;
self.states = ko.observableArray([]);
self.selectedState = ko.observable();
$.getJSON("../../WcfDS.svc/T_STATE", function (res) {
var mappedStates = $.map(res.d, function (item) { returnnew StateDef(item) });
We create a new states variable and initialize it with an obserbableArray. The, with jQuery getJSON function we read all States data through WCF Data Service.
Note two things inside $.getJSON function: we use a $.map function to retrieve datas and “translate” them in the object we want, in this case transform them in our State definition (with StateDef function). Second thing is res.d variable. It represents data collection read from dataservice, so “item” is a single state object.
All of our mapped data will become our array of data to pass to select html control.
That’s complete JavaScript code:
<scripttype="text/javascript">
function StateDef(data) {
this.id = ko.observable(data.id);
this.State = ko.observable(data.State);
}
// Overall viewmodel for this screen, along with initial state
function StatesViewModel() {
var self = this;
self.states = ko.observableArray([]);
self.selectedState = ko.observable();
$.getJSON("../../WcfDS.svc/T_STATE", function (res) {
var mappedStates = $.map(res.d, function (item) { returnnew StateDef(item) });
Suppose we have aasp.netpageanddisplay somedata from adatabase tablein aGridView.The latter isconnectedtoEntityDataSource. If we are runninga long elaborationon that table(as anupdate orother processing), the pagecontainingthe data to showcannothang anddisplayour datauntilprocessingisfinished.
That's not ever that we want....
Probablythis behavior is notwhat we want. How can wesolve it?
Using EntityDataSource ContextCreated event we can "attach" a transaction to the ObjectContext used by datasource.
First we have tomanually openthe database connection. Then, start a database transaction specifying the isolation level we want to use. In this case, we need "ReadUncommitted" so we can read all data from database, including those not yet committed (dirty).