Kendo UI:一个数据源,两个小部件

时间:2016-03-03 15:40:10

标签: javascript angularjs kendo-ui kendo-datasource kendo-map

更新: 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使用相同的DataSource对象。但是,地图的行为方式非常不可预测。

  1. 当我在模板中放置 Map之前的DropDownList 时,只会填充DropDownList。检查网络流量显示确实只有一个请求正在进行。当我首先放置Map时,它们都会被填充,并且会发出两个请求。
  2. 当我在transport.read中不使用任何承诺,但只是立即使用静态值调用options.success时,一切都按预期工作。正在进行两次通话。
  3. 我整个工作日都在梳理头发,所以任何帮助都会受到高度赞赏。

    数据源服务:

    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 个答案:

答案 0 :(得分:0)

我认为这可能是Kendo UI Map小部件中的一个错误,因为此处发生的行为根本不是人们所期望的。但是,我确实有一个解决方法。而不是将数据源作为单个对象返回,而是将其作为函数返回。这可能不太理想,但它确实有效。

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'
  }];
});

答案 1 :(得分:0)

工厂主要用于按需创建实例。见这个例子

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演示