In an AngularJS controller, I have the following defined:
app.controller('contentTypeController', ['$scope', '$log', 'abstractDataFactory', 'customFunctions',
// the abstract data factory accepts controller type parameters for RESTful CRUD
function ($scope, $log, abstractDataFactory, customFunctions) {
var dataFactory = new abstractDataFactory("/odata/ContentType");
var crudServiceBaseUrl = "/odata/ContentType";
var dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read:
function (options) {
var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");
dataFactory.getList(odataParams)
.success(function (result) {
options.success(result);
})
.error (function (error) {
console.log("data error");
});
...
This all works fine. However, I don't want to have to redefine the dataSource
in another controller, for this particular data set - ContentType, and would like to abstract it out.
As a result, I created a new dataSourceFactory
. I'm not entirely clear on or what the best strategy is for implementing this.
I was thinking that I would like to new up the dataSourceFactory
the same way I did the abstractDataFactory
from the controller, and those parameters passed on to the abstractDataFactory
from the dataSourceFactory
.
After injecting the new dataSourceFactory
into my controller, it would return various data sources, depending on the method call:
var dataSourceFactory = new dataSourceFactory("/odata/ContentType");
var dataSource = dataSourceFactory.contentType(); // .userDetails(), .someOtherData()...
From what I understand, Angular factories return functions, so I don't think this is exactly what I'm looking for.
So far, here's my non-working implementation:
Controller:
app.controller('contentTypeController', ['$scope', '$log', 'dataSourceFactory', 'customFunctions',
function ($scope, $log, dataSourceFactory, customFunctions) {
var dataSourceFactory = new dataSourceFactory("/odata/ContentType");
var dataSource = dataSourceFactory.contentTypes(); // returns a function, rather than kendo.data.DataSource object
...
DataSourceFactory:
// factory to return datasources
app.factory('dataSourceFactory', function (abstractDataFactory) {
function dataSourceFactory(odataUrlBase) {
this.dataFactory = new abstractDataFactory(odataUrlBase);
}
dataSourceFactory.prototype = {
contentTypes: function () {
new kendo.data.DataSource({
type: "odata",
transport: {
read:
function (options) {
var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");
this.dataFactory.getList(odataParams)
.success(function (result) {
options.success(result);
})
.error(function (error) {
console.log("data error");
});
}
},
batch: false,
pageSize: 10,
serverPaging: true,
change: function (e) {
console.log("change: " + e.action);
// do something with e
},
schema: {
data: function (data) {
//console.log(data)
return data.value;
},
total: function (data) {
console.log("count: " + data["odata.count"]);
return data["odata.count"];
},
model: {
id: "ContentTypeId",
fields: {
ContentTypeId: { editable: false, nullable: true },
//UserId: {editable: false, nullable: false },
Description: { type: "string", validation: { required: true } },
//msrepl_tran_version: { type: "string", validation: { required: true } }
}
}
},
error: function (e) {
//var response = JSON.parse(e.responseText);
var response = e.status;
console.log(response);
}
}) // dataSource
} // contentTypes
};
return dataSourceFactory;
});
In summary,
var dataSource = dataSourceFactory.contentTypes(); // returns a function, rather than kendo.data.DataSource object
1) Data source has to be the value of the new kendo.data.DataSource
object, rather than a function. Since the factory returns the function, how can I make use of it in my controller, and is this the right way of going about this, and if not suggestions?
2) I will have various data sources defined in the dataSourceFactory
and used as mentioned above. Is this recommended (I'm going for code reuse, and not a bunch of separate factories for each data source), and if not, suggestions?
Thanks to the subtle nudge from the comments, I was able to figure this out.
The first issue was that I wasn't actually returning anything from the function call (missing the return
statement from contentTypes:
).
Secondly, I had to define a dataFactory
inside the dataSourceFactory
that represented the abstractDataFactory
:
app.factory('dataSourceFactory', function (abstractDataFactory) {
var dataFactory;
function dataSourceFactory(odataUrlBase) {
dataFactory = new abstractDataFactory(odataUrlBase);
}
dataSourceFactory.prototype = {
contentTypes: function () {
return new kendo.data.DataSource({ ... }...
What I'm still not clear on, is if this is a good way to go - having all my data source objects returned by one factory.