Kendo UI: один источник данных, два виджета

обновление: вот ссылка для воспроизведения проблемы

по теме: это еще один мой вопрос, где подобные проблемы происходят с картой Kendo UI, возможно, это может помочь кому-то понять это! он имеет один сбой и одну рабочую версию.


я использую источник данных Kendo UI, раскрывающийся список и карту в угловом одностраничном приложении.

Я хочу использовать тот же Объект dataSource для dropdownlist и карте. Однако, карта ведет себя очень непредсказуемо.

  1. когда я ставлю DropDownList до карта в шаблоне, заполняется только выпадающий список. Проверка сетевого трафика показывает, что действительно выполняется только один запрос. Когда я ставлю карту первым, оба они заполняются и выполняются два запроса.
  2. когда я не использую никаких обещаний в 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 демо