2016-03-03 8 views
9

UPDATE:Here is a link to reproduce the problemКендо UI: Один источник данных, два виджета

СВЯЗАННЫЕ:This is another question of mine where similar problems are happening with Kendo UI Map, maybe it could help someone figure this one out! Он имеет один недостаток и один рабочий вариант.


Я использую Кендо UI в DataSource, DropDownList и карты в угловом применении одной страницы.

Я хочу использовать тот же объект DataSource как для DropDownList, так и для Map. Однако Карта ведет себя очень непредсказуемым образом.

  1. Когда я поставил DropDownList перед тем карты в шаблоне, только 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> 

Что я здесь отсутствует?

+0

Но вы _don't want_ два запроса на чтение. Это общий источник данных, поэтому почему вы хотите, чтобы он дважды запрашивал одни и те же данные? Что касается того, почему это не является обязательным для данных, нам, вероятно, нужен публичный пример, который дублирует это поведение. Трудно вывести как есть. – Brett

+0

@Brett: Действительно, я не хочу два запроса, но даже когда я отключу autoBind и вызов 'fetch' вручную, результат будет таким же. Я чувствовал, что было бы легче выяснить, могу ли я уменьшить тестовый пример до максимально возможного. Я посмотрю, могу ли я создать публичный пример. – damd

+0

Не может быть, потому что 'ourDataSource' является фабрикой, которая возвращает объект __new__ datasource? Попробуйте вернуть его в виде сингла. – Brett

ответ

0

Я считаю, что это может быть ошибкой в ​​виджетах карты 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' 
    }]; 
}); 
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"> 
 
    \t \t  
 
    <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 демо