Open pecord opened 10 years ago
In my case I noticed the schema is not available until after the first breeze query. So the call to transport._makeSchema is happening too early first time in ... else something needs to happen to fetch the metadata for the entity sooner.
Here's a data service I'm using in my angular app which uses breeze-kendo (you can easily apply the methodologies to a non-angular application. Further down, you can see how I can use the promise of the manager's fetchMetadata()
method to bind a datasource and grid after metadata is retrieved.
(function() {
'use strict';
var module = angular.module('dataService', ['loggerService']);
function DataServiceException(message) {
this.message = message;
this.name = "DataServiceException";
}
var breezeDataLayer = function(logger) {
var that = this;
var __manager;
var __baseHref;
var __initialized = false;
function getServiceRootFromPage() {
if (__baseHref) return __baseHref; // get once
var base = document.getElementsByTagName("base")[0];
var baseHref = base.getAttributeNode("href");
if (baseHref) {
__baseHref = baseHref.value;
return __baseHref;
}
return '';
};
function initialize(servicePath, newInstance) {
if (newInstance === true) {
var bm = breezeDataLayer(breeze);
bm.initialize(servicePath);
return bm;
}
if (__initialized) {
logger.error('You must request a new instance, this has already been initialized');
throw new DataServiceException('You must request a new instance, this has already been initialized');
return null;
}
if (!servicePath.startsWith('http')) {
if (!servicePath.startsWith('/')) {
servicePath = getServiceRootFromPage() + servicePath;
}
}
__manager = new breeze.EntityManager(servicePath);
__initialized = true;
return getInstance();
}
function getInstance() {
return {
Initialize: initialize,
GetManager: getManager,
CreateQuery: createQuery,
GetMetaData: getMetaData,
GetServiceRootFromPage: getServiceRootFromPage
};
}
function getManager() {
if (!__initialized) {
throw new DataServiceException('You must initialize the Data Layer.');
}
return __manager;
}
function getMetaData() {
if (!__initialized) {
throw new DataServiceException('You must initialize the Data Layer.');
}
return __manager.fetchMetadata();
}
function createQuery(entityType) {
if (!__initialized) {
throw new DataServiceException('You must initialize the Data Layer.');
}
var query = breeze.EntityQuery.from(entityType);
switch (entityType) {
case 'ItemType':
break;
case 'ItemSubType':
query = query.expand('ItemType');
break;
case 'TransactionType':
break;
case 'Customer':
break;
case 'CustomerStatus':
query = query.orderBy('StatusId');
break;
}
return query;
}
return getInstance();
};
module.factory('breezeDataLayer', ['logger', breezeDataLayer]);
})();
In my angular Controller, I take advantage of the promises to handle binding my datasources that will be used by kendo components.
Be warned if you ARE using angular as opposed to jQuery, for example, to bind your components, that this method will require that you use the k-ng-delay
directive and wrap the retrieval of your data source in the promise combined with a $scope.$apply callback.
app.controller("DataGridController", function ($scope, $http, logger, breezeDataLayer) {
var that = this;
$scope.dataLayer = breezeDataLayer.Initialize('breeze/dmd');
$scope.dataLayer.GetMetaData().then(function() {
$scope.$apply(function() {
logger.info('metadata retrieved');
$scope.getDataSource = function(entityType, pageSize) {
var dataSource = new kendo.data.breeze.Source({
manager: $scope.dataLayer.GetManager(),
query: $scope.dataLayer.CreateQuery(entityType),
serverSorting: true,
serverPaging: true,
serverFiltering: true,
pageSize: pageSize || 10
});
return dataSource;
}
$scope.getDataGridOptions = function(entityType, pageSize, editable) {
var gridOptions = {
sortable: true,
selectable: true,
dataSource: $scope.getDataSource(entityType, pageSize),
editable: editable,
autoBind: true,
height: 550,
navigatable: true,
pageable: {
refresh: true,
pageSizes: [10, 50, 100],
buttonCount: 5
},
}
return gridOptions;
}
$scope.TrxTypeGridOptions = $scope.getDataGridOptions('TransactionType', 50, false);
});
});
});
I found that if I renamed my route to match the model's name it worked. I believe this is because it uses the resource name from the query.
var typeName = meta.getEntityTypeNameForResourceName(this.query.resourceName);
@dennis To get metadata anytime check out the fetchMetadata methods on MetadataStore and EntityManager. Breeze docs explain metadat options pretty well (says the guy who wrote them)
@pecord you can give the metadata an alias resource name so it can know which type goes with that resource. See this method.
Please dont use @dennis unless you really mean to notify me :)
In the readme it says it auto generates the schema model based off the metadata. I am not seeing this happen, I noticed it because my column filters were only showing the options for string. I am using the Kendo UI chrome extension to inspect the data source. If I put my auto-generated schema back in my filters work, but I lose paging and total count.