To support OData Query, a few changes had to be made in the code.
1. Need to add a text box and button for OData Query
</pre> <div>Search: <input type="text" data-bind="value: Criteria" /> <button title="Search" data-bind="click: SearchCourse">Search</button></div> <pre>
2. Add new functions, Handle the query in Javascript
var Courses = ko.observableArray(); function GetCourses(courses, criteria) { var url = "http://localhost/ODataService/odata/Courses"; if ((typeof criteria != "undefined") && criteria !== null && criteria !== "") { url += "?$filter=" + criteria; } OData.read(url, function (data, response) { courses(JSON.parse(data)); }, function (err){ alert(err.message); } ); } GetCourses(Courses, ""); var viewModel = { Courses: Courses ,Criteria :ko.observable("") // new property for OData Query parameter } //new function for OData Query viewModel.SearchCourse = function () { GetCourses(this.Courses, this.Criteria()); } ko.applyBindings(viewModel);
if we add something like “DepartmentID gt 2” in the text box, then click search,
the page displays the following
Course ID Title Credits Department ID 1045 Calculus 4 7 3141 Trigonometry 4 7 4022 Microeconomics 3 4 4041 Macroeconomics 3 4 4061 Quantitative 2 4
About the OData query syntax, you can reference.
http://http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options
When I was doing the sample project, I have faced a few problems.
1. Datajs not support cross domain, it means that, if your service has different port in URL,
using OData.read() in javascript, error happens.
For example, if OData Service url is http://servername:8080/odata/Courses,
while the application url is http://servername:33789/webapplicationName/,
because Datajs doesn’t support cross domain access, error happens.
2. Given that the cross domain issue has been fixed, that OData service url is
is http://servername/odata/Courses, and the application url is http://servername/webapplicationName/,
call OData.read still returns an error says “no data handler”, then a data handler should be set to
replace default data handler. So the proper javascript will be the following.
var Courses = ko.observableArray(); function GetCourses(courses, criteria) { var url = "http://localhost/ODataService/odata/Courses"; if ((typeof criteria != "undefined") && criteria !== null && criteria !== "") { url += "?$filter=" + criteria; } //************************** //*** Create Handler *** //************************** var jsonHandler = { read: function (response, context) { var contentType = response.headers["Content-Type"]; if (contentType && contentType.indexOf("application/json") === 0) { response.data = response.body; } else { odata.defaultHandler.read(response, context); } }, write: function (request, context) { } } //**************************************************** //*** Replace defaultHandler to handler we created *** //**************************************************** OData.defaultHandler = jsonHandler; OData.read(url, function (data, response) { courses(JSON.parse(data)); }, function (err){ alert(err.message); } ); } GetCourses(Courses, ""); var viewModel = { Courses: Courses ,Criteria :ko.observable("") // new property for OData Query parameter } //new function for OData Query viewModel.SearchCourse = function () { GetCourses(this.Courses, this.Criteria()); } ko.applyBindings(viewModel);
Now we OData.read smoothly gets the data from OData Service and KnockoutJs is responsible
for page presentation. Keep learning.