LA.NET [EN]

Oct 28

Until now, we’ve been using static data to feed all the DataView controls we’ve been using in the MS AJAX series. Today we’ll see how we can configure the control so that it automatically gets data returned from a web service call. To get things started, we’ll start by introducing the server side code for the WCF service:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(
RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)] public class PeopleService { [OperationContract] [WebGet] public IEnumerable<Person> GetPeople() { var people = new List<Person> { new Person{ Name = "luis", Address = "fx"}, new Person{ Name = "john", Address = "lx"}, new Person{ Name = "peter", Address = "pt"} }; return people; } } [DataContract] public class Person { [DataMember(Name="name")] public String Name { get; set; } [DataMember(Name="address")] public String Address { get; set; } }


Yes, not the best code in the world, but don’t forget that I’m not interested in creating web service! What I want is to show you how to properly configure the DataView control to get data from a web service…



As you can see, PeopleService is a WCF service which has a single operation: GetPeople. This method returns a collection of Person instances (since I wanted to preserve JS naming conventions, I’ve used the DataMemberAttribute to customize the name of the properties used in JSON returned from the server).



And now we can proceed with the most important part: configuring the DataView for getting the data automatically from the server side. In this case,I’ve opted for using the declarative approach:



<head runat="server">
    <title></title>
  <script src="Scripts/MicrosoftAjax/start.debug.js" 
type="text/javascript">
</
script> <script type="text/javascript"> Sys.require([Sys.scripts.WebService,
Sys.components.dataView]); </script> </head> <body xmlns:sys="javascript:Sys" xmlns:dv="javascript:Sys.UI.DataView"> <div id="view" class="sys-template" sys:attach="dv" dv:autofetch="true" dv:httpverb="GET" dv:dataprovider="PeopleService.svc" dv:fetchoperation="GetPeople"> <div> <span>{{name}}</span>- <span>{{address}}</span> </div> </div>


We start by loading the JS files needed for communicating with the server and using the DataView control. Since we need to communicate with the server side through a remote web service method call, we need to get the base classes defined in the MicrosoftAjaxWebService.js file.



Configuring the DataView isn’t really hard since we only need to set a couple of properties:



  • autofetch: this property expects a Boolean. Setting it to true makes the DataView control fetch the data from the web service automatically during its initialization;
  • httpverb: you can use this property to set the type of HTTP method call which will be used for communicating with the server;
  • dataprovider: this property is used for setting the provider which will return the info that populates the DataView control. You can pass one of the following types to it: a reference to an object which implements the Sys.Data.IDataProvider interface (ex.: a DataContext object), a reference to a web service proxy or a string with the URI of the service. In this example, I’ve opted for using a string which identifies the URI of the web service (we’ll leave the other options for future posts);
  • fetchOperation: the name of the operation which returns the data. You’ll typically use this property when you pass a web service proxy to the DataView’s dataProvider property. In the previous snippet, I’ve opted for using it to set the name of the method (notice that this wasn’t really needed because I could have initialized the DataView’s dataProvider property with the complete path to the web service method – ie, “PeopleService.svc/GetPeople”).


Besides these properties, there are a still a couple of properties related with getting data from a remote provider:



  • fetchParameters: literal object with the parameters that should be passed for the remote service method;
  • timeout: you can use this property to set the timeout in milliseconds;
  • isFetching: read-only property which indicates if the control is performing a remote call for fetching the data;


When the DataView control is fetching data from a remote provider, you can abort that operation by invoking the abortFetch method. On the other hand, you can force a remote call by invoking the fetchData method. Calling this method starts a remote call and will automatically refresh the control with the new data that is returned from the provider.



Besides properties and methods, the control has a couple of events which you can handle:



  • fetchFailed: this event will be generated when the remote call fails;
  • fetchSucceeded: as you can probably guess, this event will be fired when the DataView control receives a successful response from the provider.


A fetchfailed handler receives three parameters:



  • a reference to the error returned from the server;
  • a custom user context object which might have been passed to the control;
  • a string (“fetchData”) which identifies the method that originated the handle call;


A fetchSucceeded handler also expects the same number of parameters as the ones that are passed to the fetchFailed handler: the main difference is that the first parameter references the data returned from the service.



And this should be enough for getting you started with getting data through remote calls. There’s still more to come, so stay tuned!

3 comments so far

  1. william apken
    12:39 pm - 10-28-2009

    Nice job as usual.

    Thanks for the explaining that 1st parameter on fetchSucceeded was the data. I could not figure out how to get my hands on the data. I load the data with a AdoNetDataContext coming from Ado Net Data Services.

    Are you going to address the fetchParameters?

    orderby, $top, $filter, expand are a few I”m currently trying to battle through.

  2. luisabreu
    12:49 pm - 10-28-2009

    Yes, I will. Getting to the $top parameters, etc will take more time though because I”ll need to dig into ado.net data services…

  3. william apken
    4:17 am - 10-29-2009

    function createHtml(html) {
    var aux = document.createElement(“div”);
    aux.innerHTML = html;
    return aux.childNodes[0];
    }

    Sys.require([Sys.components.dataView,Sys.components.adoNetDataContext]);
    Sys.onReady(function() {

    var browseHtml = “{{FirstName}}{{LastName}}”;

    var editHtml = “{{City}}{{State}}{{Zip}}”;

    /// create the browseTemplate
    templates.browseTemplate = new Sys.UI.Template(createHtml(browseHtml));

    /// create the editTemplate
    templates.editTemplate = new Sys.UI.Template(createHtml(editHtml));

    The line below does not work when I call .set_itemTemplate on the dataview.

    var browseHtml = “{{FirstName}}{{LastName}}”;

    or

    var browseHtml = “{{FirstName}}{{LastName}}”;

    It does not complain when you create the template only when you call .set_itemTemplate.

    If I do not try and set the template but allow the code in html to be the template it works fine.

    Name
    Address

    {{FirstName}}{{LastName}}{{City}}

    The code above works fine. What I”m not taking into consideration when trying to create and assign the template.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>