Kendo UI: один источник данных, два виджета
обновление: вот ссылка для воспроизведения проблемы
по теме: это еще один мой вопрос, где подобные проблемы происходят с картой Kendo UI, возможно, это может помочь кому-то понять это! он имеет один сбой и одну рабочую версию.
я использую источник данных Kendo UI, раскрывающийся список и карту в угловом одностраничном приложении.
Я хочу использовать тот же Объект dataSource для dropdownlist и карте. Однако, карта ведет себя очень непредсказуемо.
- когда я ставлю DropDownList до карта в шаблоне, заполняется только выпадающий список. Проверка сетевого трафика показывает, что действительно выполняется только один запрос. Когда я ставлю карту первым, оба они заполняются и выполняются два запроса.
- когда я не использую никаких обещаний в
transport.read
, но и просто позвонитьoptions.success
сразу со статическим значением все работает так, как ожидалось. Два звонка уже сделаны.
я тянул мои волосы над этим весь рабочий день, поэтому любая помощь высоко ценится.
данных источник:
m.factory('ourDataSource', function(foo, bar, baz) {
return new kendo.data.DataSource({
transport: {
read: function(options) {
foo().then(function (result) {
return bar(result);
}).then(function (result) {
return baz(result);
}).then(function (result) {
options.success(result);
}).catch(function (err) {
options.error(err);
});
}
}
});
});
контроллер:
m.controller('ourController', ['ourDataSource', function(ourDataSource) {
// set the data source of the dropdownlist
this.ourDataSource = ourDataSource;
// set up the map layers
this.mapLayers = [{
type: 'tile',
urlTemplate: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/#= zoom #/#= y #/#= x #',
}, {
type: 'marker',
dataSource: ourDataSource, // the same data source as before
locationField: 'Position',
titleField: 'Title'
}];
}]);
вид:
<div ng-controller="ourController as ctrl">
<select kendo-drop-down-list
k-data-text-field="'Title'"
k-data-value-field="'Title'"
k-data-source="ctrl.ourDataSource"></select>
<div kendo-map
k-zoom="2"
k-center="[1, 1]"
k-layers="ctrl.mapLayers">
</div>
</div>
что я пропустила?
2 ответов
Я считаю, что это может быть ошибка в виджете карты Kendo UI, так как поведение, происходящее здесь, совсем не то, что можно было бы ожидать. Тем не менее, у меня есть обходное решение. Вместо того чтобы возвращать источник данных как одноэлементный объект, верните его как функцию. Возможно, это не идеально,но работает.
angular.module('ourModule', ['kendo.directives'])
.factory('getDataSource', function ($q) {
return function() { // return a function that creates a new data source
return new kendo.data.DataSource({
transport: {
read: function (options) {
$q.when([
{Position: [1, 1], Title: 'First place'},
{Position: [10, 10], Title: 'Second place'}
]).then(function (result) {
options.success(result);
});
}
}
});
};
})
.controller('ourController', function (getDataSource) {
this.ourDataSource = getDataSource();
this.mapLayers = [{
type: 'tile',
urlTemplate: '...removed for brevity...'
}, {
type: 'marker',
dataSource: getDataSource(),
locationField: 'Position',
titleField: 'Title'
}];
});
завод в основном используется для создания экземпляров по требованию. См. этот пример
var app = angular.module('ourModule', ['kendo.directives']);
app.factory('dataSourceFactory', function($q) {
function dataSourceFactory() {}
dataSourceFactory.prototype = {
contentTypes: function() {
return new kendo.data.DataSource({
transport: {
read: function(options) {
$q.when(
[{
Position: [1, 1],
Title: 'First place'
}, {
Position: [10, 10],
Title: 'Second place'
}])
.then(function(result) {
options.success(result);
});
}
}
})
}
};
return dataSourceFactory;
});
app.controller('ourController', ['$scope', 'dataSourceFactory',
function($scope, dataSourceFactory) {
var dataSourceFactory = new dataSourceFactory();
$scope.mapLayers = [{
type: 'tile',
urlTemplate: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/#= zoom #/#= y #/#= x #',
}, {
type: 'marker',
dataSource: dataSourceFactory.contentTypes(), // the same data source as before
locationField: 'Position',
titleField: 'Title'
}];
$scope.ourDataSource = dataSourceFactory.contentTypes();
}
]);
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.common.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.default.min.css">
<link rel="stylesheet" href="http://kendo.cdn.telerik.com/2015.3.930/styles/kendo.mobile.all.min.css">
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/angular.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/jszip.min.js"></script>
<script src="http://kendo.cdn.telerik.com/2015.3.930/js/kendo.all.min.js"></script>
<div ng-app="ourModule">
<div ng-controller="ourController">
<kendo-drop-down-list k-data-source="ourDataSource"
k-data-text-field="'Title'"
k-data-value-field="'Title'">
</kendo-drop-down-list>
<kendo-map k-zoom="2"
k-layers="mapLayers">
</kendo-map>
</div>
</div>
посмотреть этот JSFiddle демо