Kendo UI: 一个数据源,两个小部件
Kendo UI: One data source, two widgets
更新: Here is a link to reproduce the problem
相关: This is another question of mine where similar problems are happening with Kendo UI Map, maybe it could help someone figure this one out! 它有一个失败版本和一个工作版本。
我在 Angular 单页应用程序中使用 Kendo UI 的 DataSource、DropDownList 和 Map。
我想对 DropDownList 和地图使用相同的数据源对象。但是,Map 的行为非常难以预测。
- 当我在模板中将 DropDownList 放在 Map 之前 时,只会填充 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>
我在这里错过了什么?
我认为这可能是 Kendo UI 地图小部件中的一个错误,因为此处发生的行为完全出乎人们的意料。但是,我确实有一个解决方法。 return 数据源不是作为单例对象,而是 return 作为函数。这可能并不理想,但它确实有效。
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 演示
更新: Here is a link to reproduce the problem
相关: This is another question of mine where similar problems are happening with Kendo UI Map, maybe it could help someone figure this one out! 它有一个失败版本和一个工作版本。
我在 Angular 单页应用程序中使用 Kendo UI 的 DataSource、DropDownList 和 Map。
我想对 DropDownList 和地图使用相同的数据源对象。但是,Map 的行为非常难以预测。
- 当我在模板中将 DropDownList 放在 Map 之前 时,只会填充 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>
我在这里错过了什么?
我认为这可能是 Kendo UI 地图小部件中的一个错误,因为此处发生的行为完全出乎人们的意料。但是,我确实有一个解决方法。 return 数据源不是作为单例对象,而是 return 作为函数。这可能并不理想,但它确实有效。
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 演示